Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
lgc.c File Reference
#include <string.h>
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"

Go to the source code of this file.

Macros

#define lgc_c
 
#define LUA_CORE
 
#define GCSWEEPCOST   ((sizeof(TString) + 4) / 4)
 
#define GCSWEEPMAX   (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
 
#define GCFINALIZENUM   4
 
#define STEPMULADJ   200
 
#define PAUSEADJ   100
 
#define maskcolors   (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))
 
#define makewhite(g, x)    (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
 
#define white2gray(x)   resetbits(gch(x)->marked, WHITEBITS)
 
#define black2gray(x)   resetbit(gch(x)->marked, BLACKBIT)
 
#define isfinalized(x)   testbit(gch(x)->marked, FINALIZEDBIT)
 
#define checkdeadkey(n)   lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
 
#define checkconsistency(obj)    lua_longassert(!iscollectable(obj) || righttt(obj))
 
#define markvalue(g, o)
 
#define markobject(g, t)
 
#define gnodelast(h)   gnode(h, cast(size_t, sizenode(h)))
 
#define linktable(h, p)   ((h)->gclist = *(p), *(p) = obj2gco(h))
 
#define sweepwholelist(L, p)   sweeplist(L,p,MAX_LUMEM)
 
#define sweepphases    (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
 

Functions

static void reallymarkobject (global_State *g, GCObject *o)
 
static void removeentry (Node *n)
 
static int iscleared (global_State *g, const TValue *o)
 
void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v)
 
void luaC_barrierback_ (lua_State *L, GCObject *o)
 
LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c)
 
void luaC_checkupvalcolor (global_State *g, UpVal *uv)
 
GCObjectluaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, int offset)
 
static void markmt (global_State *g)
 
static void markbeingfnz (global_State *g)
 
static void remarkupvals (global_State *g)
 
static void restartcollection (global_State *g)
 
static void traverseweakvalue (global_State *g, Table *h)
 
static int traverseephemeron (global_State *g, Table *h)
 
static void traversestrongtable (global_State *g, Table *h)
 
static lu_mem traversetable (global_State *g, Table *h)
 
static int traverseproto (global_State *g, Proto *f)
 
static lu_mem traverseCclosure (global_State *g, CClosure *cl)
 
static lu_mem traverseLclosure (global_State *g, LClosure *cl)
 
static lu_mem traversestack (global_State *g, lua_State *th)
 
static void propagatemark (global_State *g)
 
static void propagateall (global_State *g)
 
static void propagatelist (global_State *g, GCObject *l)
 
static void retraversegrays (global_State *g)
 
static void convergeephemerons (global_State *g)
 
static void clearkeys (global_State *g, GCObject *l, GCObject *f)
 
static void clearvalues (global_State *g, GCObject *l, GCObject *f)
 
static void freeobj (lua_State *L, GCObject *o)
 
static GCObject ** sweeplist (lua_State *L, GCObject **p, lu_mem count)
 
static void sweepthread (lua_State *L, lua_State *L1)
 
static GCObject ** sweeptolive (lua_State *L, GCObject **p, int *n)
 
static void checkSizes (lua_State *L)
 
static GCObjectudata2finalize (global_State *g)
 
static void dothecall (lua_State *L, void *ud)
 
static void GCTM (lua_State *L, int propagateerrors)
 
static void separatetobefnz (lua_State *L, int all)
 
void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt)
 
static void setpause (global_State *g, l_mem estimate)
 
static int entersweep (lua_State *L)
 
void luaC_changemode (lua_State *L, int mode)
 
static void callallpendingfinalizers (lua_State *L, int propagateerrors)
 
void luaC_freeallobjects (lua_State *L)
 
static l_mem atomic (lua_State *L)
 
static lu_mem singlestep (lua_State *L)
 
void luaC_runtilstate (lua_State *L, int statesmask)
 
static void generationalcollection (lua_State *L)
 
static void incstep (lua_State *L)
 
void luaC_forcestep (lua_State *L)
 
void luaC_step (lua_State *L)
 
void luaC_fullgc (lua_State *L, int isemergency)
 

Macro Definition Documentation

◆ black2gray

#define black2gray ( x)    resetbit(gch(x)->marked, BLACKBIT)

◆ checkconsistency

#define checkconsistency ( obj)     lua_longassert(!iscollectable(obj) || righttt(obj))

Definition at line 71 of file lua-5.2.4/src/lgc.c.

71#define checkconsistency(obj) \
72 lua_longassert(!iscollectable(obj) || righttt(obj))

◆ checkdeadkey

#define checkdeadkey ( n)    lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))

Definition at line 68 of file lua-5.2.4/src/lgc.c.

Referenced by traverseephemeron(), traversestrongtable(), and traverseweakvalue().

◆ GCFINALIZENUM

#define GCFINALIZENUM   4

Definition at line 37 of file lua-5.2.4/src/lgc.c.

Referenced by luaC_forcestep().

◆ GCSWEEPCOST

#define GCSWEEPCOST   ((sizeof(TString) + 4) / 4)

Definition at line 31 of file lua-5.2.4/src/lgc.c.

Referenced by singlestep().

◆ GCSWEEPMAX

#define GCSWEEPMAX   (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))

Definition at line 34 of file lua-5.2.4/src/lgc.c.

Referenced by singlestep().

◆ gnodelast

#define gnodelast ( h)    gnode(h, cast(size_t, sizenode(h)))

◆ isfinalized

#define isfinalized ( x)    testbit(gch(x)->marked, FINALIZEDBIT)

Definition at line 66 of file lua-5.2.4/src/lgc.c.

Referenced by luaC_checkfinalizer(), separatetobefnz(), and udata2finalize().

◆ lgc_c

#define lgc_c

Definition at line 9 of file lua-5.2.4/src/lgc.c.

◆ linktable

#define linktable ( h,
p )   ((h)->gclist = *(p), *(p) = obj2gco(h))

◆ LUA_CORE

#define LUA_CORE

Definition at line 10 of file lua-5.2.4/src/lgc.c.

◆ makewhite

#define makewhite ( g,
x )    (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))

Definition at line 59 of file lua-5.2.4/src/lgc.c.

59#define makewhite(g,x) \
60 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))

Referenced by luaC_barrier_(), luaC_checkfinalizer(), luaC_checkupvalcolor(), markbeingfnz(), and udata2finalize().

◆ markobject

#define markobject ( g,
t )
Value:
{ if ((t) && iswhite(obj2gco(t))) \
reallymarkobject(g, obj2gco(t)); }
#define iswhite(x)
#define obj2gco(v)

Definition at line 78 of file lua-5.2.4/src/lgc.c.

78#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \
79 reallymarkobject(g, obj2gco(t)); }

Referenced by atomic(), iscleared(), markmt(), reallymarkobject(), restartcollection(), traverseLclosure(), traverseproto(), and traversetable().

◆ markvalue

#define markvalue ( g,
o )
Value:
#define valiswhite(x)
#define gcvalue(o)
static void reallymarkobject(global_State *g, GCObject *o)
#define checkconsistency(obj)

Definition at line 75 of file lua-5.2.4/src/lgc.c.

75#define markvalue(g,o) { checkconsistency(o); \
76 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }

Referenced by atomic(), luaC_checkupvalcolor(), reallymarkobject(), remarkupvals(), restartcollection(), traverseCclosure(), traverseproto(), traversestack(), traversestrongtable(), and traverseweakvalue().

◆ maskcolors

#define maskcolors   (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))

Definition at line 58 of file lua-5.2.4/src/lgc.c.

Referenced by sweeplist().

◆ PAUSEADJ

#define PAUSEADJ   100

Definition at line 51 of file lua-5.2.4/src/lgc.c.

Referenced by setpause().

◆ STEPMULADJ

#define STEPMULADJ   200

Definition at line 44 of file lua-5.2.4/src/lgc.c.

Referenced by incstep().

◆ sweepphases

#define sweepphases    (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))

Definition at line 924 of file lua-5.2.4/src/lgc.c.

924#define sweepphases \
925 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))

Referenced by luaC_changemode().

◆ sweepwholelist

#define sweepwholelist ( L,
p )   sweeplist(L,p,MAX_LUMEM)

Definition at line 690 of file lua-5.2.4/src/lgc.c.

Referenced by luaC_freeallobjects(), singlestep(), and sweepthread().

◆ white2gray

#define white2gray ( x)    resetbits(gch(x)->marked, WHITEBITS)

Definition at line 62 of file lua-5.2.4/src/lgc.c.

Referenced by reallymarkobject().

Function Documentation

◆ atomic()

static l_mem atomic ( lua_State * L)
static

Definition at line 999 of file lua-5.2.4/src/lgc.c.

999 {
1000 global_State *g = G(L);
1001 l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */
1002 GCObject *origweak, *origall;
1004 markobject(g, L); /* mark running thread */
1005 /* registry and global metatables may be changed by API */
1006 markvalue(g, &g->l_registry);
1007 markmt(g); /* mark basic metatables */
1008 /* remark occasional upvalues of (maybe) dead threads */
1009 remarkupvals(g);
1010 propagateall(g); /* propagate changes */
1011 work += g->GCmemtrav; /* stop counting (do not (re)count grays) */
1012 /* traverse objects caught by write barrier and by 'remarkupvals' */
1013 retraversegrays(g);
1014 work -= g->GCmemtrav; /* restart counting */
1016 /* at this point, all strongly accessible objects are marked. */
1017 /* clear values from weak tables, before checking finalizers */
1018 clearvalues(g, g->weak, NULL);
1019 clearvalues(g, g->allweak, NULL);
1020 origweak = g->weak; origall = g->allweak;
1021 work += g->GCmemtrav; /* stop counting (objects being finalized) */
1022 separatetobefnz(L, 0); /* separate objects to be finalized */
1023 markbeingfnz(g); /* mark objects that will be finalized */
1024 propagateall(g); /* remark, to propagate `preserveness' */
1025 work -= g->GCmemtrav; /* restart counting */
1027 /* at this point, all resurrected objects are marked. */
1028 /* remove dead objects from weak tables */
1029 clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */
1030 clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */
1031 /* clear values from resurrected weak tables */
1032 clearvalues(g, g->weak, origweak);
1033 clearvalues(g, g->allweak, origall);
1034 g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */
1035 work += g->GCmemtrav; /* complete counting */
1036 return work; /* estimate of memory marked by 'atomic' */
1037}
#define NULL
Definition gmacros.h:924
#define otherwhite(g)
#define cast_byte(i)
#define lua_assert(c)
LUAI_MEM l_mem
#define cast(t, exp)
#define G(L)
#define markvalue(g, o)
static void convergeephemerons(global_State *g)
static void markbeingfnz(global_State *g)
#define markobject(g, t)
static void remarkupvals(global_State *g)
static void clearvalues(global_State *g, GCObject *l, GCObject *f)
static void propagateall(global_State *g)
static void markmt(global_State *g)
static void retraversegrays(global_State *g)
static void clearkeys(global_State *g, GCObject *l, GCObject *f)
static void separatetobefnz(lua_State *L, int all)
struct lua_State * mainthread

References global_State::allweak, cast, cast_byte, clearkeys(), clearvalues(), convergeephemerons(), global_State::currentwhite, global_State::ephemeron, G, global_State::GCmemtrav, iswhite, global_State::l_registry, lua_assert, global_State::mainthread, markbeingfnz(), markmt(), markobject, markvalue, NULL, obj2gco, otherwhite, propagateall(), remarkupvals(), retraversegrays(), separatetobefnz(), and global_State::weak.

Referenced by singlestep().

◆ callallpendingfinalizers()

static void callallpendingfinalizers ( lua_State * L,
int propagateerrors )
static

Definition at line 974 of file lua-5.2.4/src/lgc.c.

974 {
975 global_State *g = G(L);
976 while (g->tobefnz) {
978 GCTM(L, propagateerrors);
979 }
980}
static void GCTM(lua_State *L, int propagateerrors)
#define resetoldbit(o)

References G, GCTM(), resetoldbit, and global_State::tobefnz.

Referenced by luaC_freeallobjects(), and luaC_fullgc().

◆ checkSizes()

static void checkSizes ( lua_State * L)
static

Definition at line 778 of file lua-5.2.4/src/lgc.c.

778 {
779 global_State *g = G(L);
780 if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */
781 int hs = g->strt.size / 2; /* half the size of the string table */
782 if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */
783 luaS_resize(L, hs); /* halve its size */
784 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
785 }
786}
LUAI_UINT32 lu_int32
void luaS_resize(lua_State *L, int newsize)
#define luaZ_freebuffer(L, buff)
#define KGC_EMERGENCY

References global_State::buff, cast, G, global_State::gckind, KGC_EMERGENCY, luaS_resize(), luaZ_freebuffer, stringtable::nuse, stringtable::size, and global_State::strt.

Referenced by singlestep().

◆ clearkeys()

static void clearkeys ( global_State * g,
GCObject * l,
GCObject * f )
static

Definition at line 625 of file lua-5.2.4/src/lgc.c.

625 {
626 for (; l != f; l = gco2t(l)->gclist) {
627 Table *h = gco2t(l);
628 Node *n, *limit = gnodelast(h);
629 for (n = gnode(h, 0); n < limit; n++) {
630 if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
631 setnilvalue(gval(n)); /* remove value ... */
632 removeentry(n); /* and remove entry from table */
633 }
634 }
635 }
636}
#define ttisnil(o)
#define setnilvalue(obj)
#define gnode(t, i)
#define gval(n)
#define gkey(n)
static int iscleared(global_State *g, const TValue *o)
#define gnodelast(h)
static void removeentry(Node *n)
#define gco2t(o)

References gco2t, gkey, gnode, gnodelast, gval, iscleared(), removeentry(), setnilvalue, and ttisnil.

Referenced by atomic().

◆ clearvalues()

static void clearvalues ( global_State * g,
GCObject * l,
GCObject * f )
static

Definition at line 643 of file lua-5.2.4/src/lgc.c.

643 {
644 for (; l != f; l = gco2t(l)->gclist) {
645 Table *h = gco2t(l);
646 Node *n, *limit = gnodelast(h);
647 int i;
648 for (i = 0; i < h->sizearray; i++) {
649 TValue *o = &h->array[i];
650 if (iscleared(g, o)) /* value was collected? */
651 setnilvalue(o); /* remove value */
652 }
653 for (n = gnode(h, 0); n < limit; n++) {
654 if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
655 setnilvalue(gval(n)); /* remove value ... */
656 removeentry(n); /* and remove entry from table */
657 }
658 }
659 }
660}

References Table::array, gco2t, gnode, gnodelast, gval, iscleared(), removeentry(), setnilvalue, Table::sizearray, and ttisnil.

Referenced by atomic().

◆ convergeephemerons()

static void convergeephemerons ( global_State * g)
static

Definition at line 594 of file lua-5.2.4/src/lgc.c.

594 {
595 int changed;
596 do {
597 GCObject *w;
598 GCObject *next = g->ephemeron; /* get ephemeron list */
599 g->ephemeron = NULL; /* tables will return to this list when traversed */
600 changed = 0;
601 while ((w = next) != NULL) {
602 next = gco2t(w)->gclist;
603 if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */
604 propagateall(g); /* propagate changes */
605 changed = 1; /* will have to revisit all ephemeron tables */
606 }
607 }
608 } while (changed);
609}
#define next(ls)
static int traverseephemeron(global_State *g, Table *h)

References global_State::ephemeron, gco2t, next, NULL, propagateall(), and traverseephemeron().

Referenced by atomic().

◆ dothecall()

static void dothecall ( lua_State * L,
void * ud )
static

Definition at line 803 of file lua-5.2.4/src/lgc.c.

803 {
804 UNUSED(ud);
805 luaD_call(L, L->top - 2, 0, 0);
806}
void luaD_call(lua_State *L, StkId func, int nResults)
#define UNUSED(x)

References luaD_call(), lua_State::top, and UNUSED.

Referenced by GCTM().

◆ entersweep()

static int entersweep ( lua_State * L)
static

Definition at line 936 of file lua-5.2.4/src/lgc.c.

936 {
937 global_State *g = G(L);
938 int n = 0;
940 lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);
941 /* prepare to sweep strings, finalizable objects, and regular objects */
942 g->sweepstrgc = 0;
943 g->sweepfin = sweeptolive(L, &g->finobj, &n);
944 g->sweepgc = sweeptolive(L, &g->allgc, &n);
945 return n;
946}
#define GCSsweepstring
static GCObject ** sweeptolive(lua_State *L, GCObject **p, int *n)

References global_State::allgc, global_State::finobj, G, GCSsweepstring, global_State::gcstate, lua_assert, NULL, global_State::sweepfin, global_State::sweepgc, global_State::sweepstrgc, and sweeptolive().

Referenced by luaC_changemode(), luaC_fullgc(), and singlestep().

◆ freeobj()

static void freeobj ( lua_State * L,
GCObject * o )
static

Definition at line 663 of file lua-5.2.4/src/lgc.c.

663 {
664 switch (gch(o)->tt) {
665 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
666 case LUA_TLCL: {
667 luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));
668 break;
669 }
670 case LUA_TCCL: {
671 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
672 break;
673 }
674 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
675 case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
676 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
677 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
678 case LUA_TSHRSTR:
679 G(L)->strt.nuse--;
680 /* go through */
681 case LUA_TLNGSTR: {
682 luaM_freemem(L, o, sizestring(gco2ts(o)));
683 break;
684 }
685 default: lua_assert(0);
686 }
687}
void luaF_freeproto(lua_State *L, Proto *f)
void luaF_freeupval(lua_State *L, UpVal *uv)
#define sizeLclosure(n)
#define sizeCclosure(n)
#define luaM_freemem(L, b, s)
#define LUA_TUPVAL
#define LUA_TPROTO
void luaE_freethread(lua_State *L, lua_State *L1)
#define gco2th(o)
#define gco2u(o)
#define gco2p(o)
#define gco2uv(o)
#define gco2ts(o)
#define sizeudata(u)
#define sizestring(s)
void luaH_free(lua_State *L, Table *t)
#define LUA_TTHREAD
#define LUA_TTABLE
#define LUA_TUSERDATA
#define LUA_TSHRSTR
#define LUA_TLCL
#define LUA_TLNGSTR
#define LUA_TCCL
#define gco2ccl(o)
#define gch(o)
#define gco2lcl(o)

References G, gch, gco2ccl, gco2lcl, gco2p, gco2t, gco2th, gco2ts, gco2u, gco2uv, lua_assert, LUA_TCCL, LUA_TLCL, LUA_TLNGSTR, LUA_TPROTO, LUA_TSHRSTR, LUA_TTABLE, LUA_TTHREAD, LUA_TUPVAL, LUA_TUSERDATA, luaE_freethread(), luaF_freeproto(), luaF_freeupval(), luaH_free(), luaM_freemem, sizeCclosure, sizeLclosure, sizestring, and sizeudata.

Referenced by sweeplist().

◆ GCTM()

static void GCTM ( lua_State * L,
int propagateerrors )
static

Definition at line 809 of file lua-5.2.4/src/lgc.c.

809 {
810 global_State *g = G(L);
811 const TValue *tm;
812 TValue v;
813 setgcovalue(L, &v, udata2finalize(g));
814 tm = luaT_gettmbyobj(L, &v, TM_GC);
815 if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */
816 int status;
817 lu_byte oldah = L->allowhook;
818 int running = g->gcrunning;
819 L->allowhook = 0; /* stop debug hooks during GC metamethod */
820 g->gcrunning = 0; /* avoid GC steps */
821 setobj2s(L, L->top, tm); /* push finalizer... */
822 setobj2s(L, L->top + 1, &v); /* ... and its argument */
823 L->top += 2; /* and (next line) call the finalizer */
824 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
825 L->allowhook = oldah; /* restore hooks */
826 g->gcrunning = running; /* restore state */
827 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
828 if (status == LUA_ERRRUN) { /* is there an error object? */
829 const char *msg = (ttisstring(L->top - 1))
830 ? svalue(L->top - 1)
831 : "no message";
832 luaO_pushfstring(L, "error in __gc metamethod (%s)", msg);
833 status = LUA_ERRGCMM; /* error in __gc metamethod */
834 }
835 luaD_throw(L, status); /* re-throw error */
836 }
837 }
838}
int luaD_pcall(lua_State *L, Pfunc func, void *u, ptrdiff_t old_top, ptrdiff_t ef)
void luaD_throw(lua_State *L, int errcode)
#define savestack(L, p)
unsigned char lu_byte
const char * luaO_pushfstring(lua_State *L, const char *fmt,...)
#define setobj2s
#define ttisfunction(o)
#define ttisstring(o)
#define svalue(o)
const TValue * luaT_gettmbyobj(lua_State *L, const TValue *o, TMS event)
@ TM_GC
#define LUA_ERRRUN
static GCObject * udata2finalize(global_State *g)
static void dothecall(lua_State *L, void *ud)
#define setgcovalue(L, obj, x)
#define LUA_OK
#define LUA_ERRGCMM

References lua_State::allowhook, dothecall(), G, global_State::gcrunning, LUA_ERRGCMM, LUA_ERRRUN, LUA_OK, luaD_pcall(), luaD_throw(), luaO_pushfstring(), luaT_gettmbyobj(), NULL, savestack, setgcovalue, setobj2s, svalue, TM_GC, lua_State::top, ttisfunction, ttisstring, and udata2finalize().

Referenced by callallpendingfinalizers(), and luaC_forcestep().

◆ generationalcollection()

static void generationalcollection ( lua_State * L)
static

Definition at line 1117 of file lua-5.2.4/src/lgc.c.

1117 {
1118 global_State *g = G(L);
1120 if (g->GCestimate == 0) { /* signal for another major collection? */
1121 luaC_fullgc(L, 0); /* perform a full regular collection */
1122 g->GCestimate = gettotalbytes(g); /* update control */
1123 }
1124 else {
1125 lu_mem estimate = g->GCestimate;
1126 luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */
1127 g->gcstate = GCSpropagate; /* skip restart */
1128 if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
1129 g->GCestimate = 0; /* signal for a major collection */
1130 else
1131 g->GCestimate = estimate; /* keep estimate from last major coll. */
1132
1133 }
1134 setpause(g, gettotalbytes(g));
1136}
#define GCSpropagate
#define GCSpause
#define bitmask(b)
LUAI_UMEM lu_mem
static void setpause(global_State *g, l_mem estimate)
void luaC_runtilstate(lua_State *L, int statesmask)
void luaC_fullgc(lua_State *L, int isemergency)
#define gettotalbytes(g)

References bitmask, G, global_State::GCestimate, global_State::gcmajorinc, GCSpause, GCSpropagate, global_State::gcstate, gettotalbytes, lua_assert, luaC_fullgc(), luaC_runtilstate(), and setpause().

Referenced by luaC_forcestep().

◆ incstep()

static void incstep ( lua_State * L)
static

Definition at line 1139 of file lua-5.2.4/src/lgc.c.

1139 {
1140 global_State *g = G(L);
1141 l_mem debt = g->GCdebt;
1142 int stepmul = g->gcstepmul;
1143 if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
1144 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
1145 debt = (debt / STEPMULADJ) + 1;
1146 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
1147 do { /* always perform at least one single step */
1148 lu_mem work = singlestep(L); /* do some work */
1149 debt -= work;
1150 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1151 if (g->gcstate == GCSpause)
1152 setpause(g, g->GCestimate); /* pause until next cycle */
1153 else {
1154 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1155 luaE_setdebt(g, debt);
1156 }
1157}
#define GCSTEPSIZE
#define STEPMULADJ
static lu_mem singlestep(lua_State *L)
#define MAX_LMEM
void luaE_setdebt(global_State *g, l_mem debt)

References G, global_State::GCdebt, global_State::GCestimate, GCSpause, global_State::gcstate, global_State::gcstepmul, GCSTEPSIZE, luaE_setdebt(), MAX_LMEM, setpause(), singlestep(), and STEPMULADJ.

Referenced by luaC_forcestep().

◆ iscleared()

static int iscleared ( global_State * g,
const TValue * o )
static

Definition at line 121 of file lua-5.2.4/src/lgc.c.

121 {
122 if (!iscollectable(o)) return 0;
123 else if (ttisstring(o)) {
124 markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */
125 return 0;
126 }
127 else return iswhite(gcvalue(o));
128}
#define rawtsvalue(o)
#define iscollectable(o)

References gcvalue, iscollectable, iswhite, markobject, rawtsvalue, and ttisstring.

Referenced by clearkeys(), clearvalues(), traverseephemeron(), and traverseweakvalue().

◆ luaC_barrier_()

void luaC_barrier_ ( lua_State * L,
GCObject * o,
GCObject * v )

Definition at line 135 of file lua-5.2.4/src/lgc.c.

135 {
136 global_State *g = G(L);
137 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
139 lua_assert(gch(o)->tt != LUA_TTABLE);
140 if (keepinvariantout(g)) /* must keep invariant? */
141 reallymarkobject(g, v); /* restore invariant */
142 else { /* sweep phase */
144 makewhite(g, o); /* mark main obj. as white to avoid other barriers */
145 }
146}
#define isblack(x)
#define isdead(g, v)
#define makewhite(g, x)
#define issweepphase(g)
#define keepinvariantout(g)

References G, gch, GCSpause, global_State::gcstate, isblack, isdead, issweepphase, iswhite, keepinvariantout, lua_assert, LUA_TTABLE, makewhite, and reallymarkobject().

◆ luaC_barrierback_()

void luaC_barrierback_ ( lua_State * L,
GCObject * o )

Definition at line 155 of file lua-5.2.4/src/lgc.c.

155 {
156 global_State *g = G(L);
157 lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE);
158 black2gray(o); /* make object gray (again) */
159 gco2t(o)->gclist = g->grayagain;
160 g->grayagain = o;
161}
#define black2gray(x)

References black2gray, G, gch, gco2t, global_State::grayagain, isblack, isdead, lua_assert, and LUA_TTABLE.

◆ luaC_barrierproto_()

LUAI_FUNC void luaC_barrierproto_ ( lua_State * L,
Proto * p,
Closure * c )

Definition at line 172 of file lua-5.2.4/src/lgc.c.

172 {
173 global_State *g = G(L);
175 if (p->cache == NULL) { /* first time? */
176 luaC_objbarrier(L, p, c);
177 }
178 else { /* use a backward barrier */
179 black2gray(obj2gco(p)); /* make prototype gray (again) */
180 p->gclist = g->grayagain;
181 g->grayagain = obj2gco(p);
182 }
183}
#define luaC_objbarrier(L, p, o)
union Closure * cache
GCObject * gclist

References black2gray, Proto::cache, G, Proto::gclist, global_State::grayagain, isblack, lua_assert, luaC_objbarrier, NULL, and obj2gco.

◆ luaC_changemode()

void luaC_changemode ( lua_State * L,
int mode )

Definition at line 952 of file lua-5.2.4/src/lgc.c.

952 {
953 global_State *g = G(L);
954 if (mode == g->gckind) return; /* nothing to change */
955 if (mode == KGC_GEN) { /* change to generational mode */
956 /* make sure gray lists are consistent */
959 g->gckind = KGC_GEN;
960 }
961 else { /* change to incremental mode */
962 /* sweep all objects to turn them back to white
963 (as white has not changed, nothing extra will be collected) */
964 g->gckind = KGC_NORMAL;
965 entersweep(L);
967 }
968}
static int entersweep(lua_State *L)
#define sweepphases
#define KGC_GEN
#define KGC_NORMAL

References bitmask, entersweep(), G, global_State::GCestimate, global_State::gckind, GCSpropagate, gettotalbytes, KGC_GEN, KGC_NORMAL, luaC_runtilstate(), and sweepphases.

Referenced by lua_gc(), and lua_gc().

◆ luaC_checkfinalizer()

void luaC_checkfinalizer ( lua_State * L,
GCObject * o,
Table * mt )

Definition at line 873 of file lua-5.2.4/src/lgc.c.

873 {
874 global_State *g = G(L);
875 if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */
876 isfinalized(o) || /* ... or is finalized... */
877 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
878 return; /* nothing to be done */
879 else { /* move 'o' to 'finobj' list */
880 GCObject **p;
881 GCheader *ho = gch(o);
882 if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */
884 g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
885 }
886 /* search for pointer pointing to 'o' */
887 for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
888 *p = ho->next; /* remove 'o' from root list */
889 ho->next = g->finobj; /* link it in list 'finobj' */
890 g->finobj = o;
891 l_setbit(ho->marked, SEPARATED); /* mark it as such */
892 if (!keepinvariantout(g)) /* not keeping invariant? */
893 makewhite(g, o); /* "sweep" object */
894 else
895 resetoldbit(o); /* see MOVE OLD rule */
896 }
897}
#define testbit(x, b)
#define l_setbit(x, b)
#define gfasttm(g, et, e)
#define isfinalized(x)
#define SEPARATED

References global_State::allgc, global_State::finobj, G, gch, gfasttm, isfinalized, issweepphase, keepinvariantout, l_setbit, lua_assert, makewhite, NULL, resetoldbit, SEPARATED, global_State::sweepgc, sweeptolive(), testbit, and TM_GC.

Referenced by lua_setmetatable().

◆ luaC_checkupvalcolor()

void luaC_checkupvalcolor ( global_State * g,
UpVal * uv )

Definition at line 190 of file lua-5.2.4/src/lgc.c.

190 {
191 GCObject *o = obj2gco(uv);
192 lua_assert(!isblack(o)); /* open upvalues are never black */
193 if (isgray(o)) {
194 if (keepinvariant(g)) {
195 resetoldbit(o); /* see MOVE OLD rule */
196 gray2black(o); /* it is being visited now */
197 markvalue(g, uv->v);
198 }
199 else {
201 makewhite(g, o);
202 }
203 }
204}
#define isgray(x)
#define gray2black(x)
#define keepinvariant(g)

References gray2black, isblack, isgray, issweepphase, keepinvariant, lua_assert, makewhite, markvalue, obj2gco, resetoldbit, and UpVal::v.

Referenced by luaF_close().

◆ luaC_forcestep()

void luaC_forcestep ( lua_State * L)

Definition at line 1163 of file lua-5.2.4/src/lgc.c.

1163 {
1164 global_State *g = G(L);
1165 int i;
1167 else incstep(L);
1168 /* run a few finalizers (or all of them at the end of a collect cycle) */
1169 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1170 GCTM(L, 1); /* call one finalizer */
1171}
#define GCFINALIZENUM
static void incstep(lua_State *L)
static void generationalcollection(lua_State *L)
#define isgenerational(g)

References G, GCFINALIZENUM, GCSpause, global_State::gcstate, GCTM(), generationalcollection(), incstep(), isgenerational, and global_State::tobefnz.

Referenced by lua_gc(), and luaC_step().

◆ luaC_freeallobjects()

void luaC_freeallobjects ( lua_State * L)

Definition at line 983 of file lua-5.2.4/src/lgc.c.

983 {
984 global_State *g = G(L);
985 int i;
986 separatetobefnz(L, 1); /* separate all objects with finalizers */
987 lua_assert(g->finobj == NULL);
989 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
990 g->gckind = KGC_NORMAL;
991 sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */
992 sweepwholelist(L, &g->allgc);
993 for (i = 0; i < g->strt.size; i++) /* free all string lists */
994 sweepwholelist(L, &g->strt.hash[i]);
995 lua_assert(g->strt.nuse == 0);
996}
#define WHITEBITS
#define sweepwholelist(L, p)
static void callallpendingfinalizers(lua_State *L, int propagateerrors)

References global_State::allgc, callallpendingfinalizers(), global_State::currentwhite, global_State::finobj, G, global_State::gckind, stringtable::hash, KGC_NORMAL, lua_assert, NULL, stringtable::nuse, separatetobefnz(), stringtable::size, global_State::strt, sweepwholelist, and WHITEBITS.

Referenced by close_state(), close_state(), and close_state().

◆ luaC_fullgc()

void luaC_fullgc ( lua_State * L,
int isemergency )

Definition at line 1189 of file lua-5.2.4/src/lgc.c.

1189 {
1190 global_State *g = G(L);
1191 int origkind = g->gckind;
1192 lua_assert(origkind != KGC_EMERGENCY);
1193 if (isemergency) /* do not run finalizers during emergency GC */
1194 g->gckind = KGC_EMERGENCY;
1195 else {
1196 g->gckind = KGC_NORMAL;
1198 }
1199 if (keepinvariant(g)) { /* may there be some black objects? */
1200 /* must sweep all objects to turn them back to white
1201 (as white has not changed, nothing will be collected) */
1202 entersweep(L);
1203 }
1204 /* finish any pending sweep phase to start a new cycle */
1206 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
1207 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */
1208 if (origkind == KGC_GEN) { /* generational mode? */
1209 /* generational mode must be kept in propagate phase */
1211 }
1212 g->gckind = origkind;
1213 setpause(g, gettotalbytes(g));
1214 if (!isemergency) /* do not run finalizers during emergency GC */
1216}

References bitmask, callallpendingfinalizers(), entersweep(), G, global_State::gckind, GCSpause, GCSpropagate, gettotalbytes, keepinvariant, KGC_EMERGENCY, KGC_GEN, KGC_NORMAL, lua_assert, luaC_runtilstate(), and setpause().

Referenced by generationalcollection().

◆ luaC_newobj()

GCObject * luaC_newobj ( lua_State * L,
int tt,
size_t sz,
GCObject ** list,
int offset )

Definition at line 212 of file lua-5.2.4/src/lgc.c.

213 {
214 global_State *g = G(L);
215 char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz));
216 GCObject *o = obj2gco(raw + offset);
217 if (list == NULL)
218 list = &g->allgc; /* standard list for collectable objects */
219 gch(o)->marked = luaC_white(g);
220 gch(o)->tt = tt;
221 gch(o)->next = *list;
222 *list = o;
223 return o;
224}
#define luaC_white(g)
#define luaM_newobject(L, tag, s)
#define novariant(x)

References global_State::allgc, cast, G, gch, luaC_white, luaM_newobject, novariant, NULL, and obj2gco.

Referenced by createstrobj(), createstrobj(), createstrobj(), lua_newthread(), luaF_findupval(), luaF_initupvals(), luaF_newCclosure(), luaF_newCclosure(), luaF_newLclosure(), luaF_newLclosure(), luaF_newproto(), luaF_newupval(), luaH_new(), luaS_newudata(), luaS_newudata(), luaS_newudata(), and newupval().

◆ luaC_runtilstate()

void luaC_runtilstate ( lua_State * L,
int statesmask )

Definition at line 1110 of file lua-5.2.4/src/lgc.c.

1110 {
1111 global_State *g = G(L);
1112 while (!testbit(statesmask, g->gcstate))
1113 singlestep(L);
1114}

References G, global_State::gcstate, singlestep(), and testbit.

Referenced by generationalcollection(), luaC_changemode(), luaC_fullgc(), and luaS_resize().

◆ luaC_step()

void luaC_step ( lua_State * L)

Definition at line 1177 of file lua-5.2.4/src/lgc.c.

1177 {
1178 global_State *g = G(L);
1179 if (g->gcrunning) luaC_forcestep(L);
1180 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
1181}
void luaC_forcestep(lua_State *L)

References G, global_State::gcrunning, GCSTEPSIZE, luaC_forcestep(), and luaE_setdebt().

◆ markbeingfnz()

static void markbeingfnz ( global_State * g)
static

Definition at line 311 of file lua-5.2.4/src/lgc.c.

311 {
312 GCObject *o;
313 for (o = g->tobefnz; o != NULL; o = gch(o)->next) {
314 makewhite(g, o);
315 reallymarkobject(g, o);
316 }
317}

References gch, makewhite, NULL, reallymarkobject(), and global_State::tobefnz.

Referenced by atomic(), and restartcollection().

◆ markmt()

static void markmt ( global_State * g)
static

Definition at line 301 of file lua-5.2.4/src/lgc.c.

301 {
302 int i;
303 for (i=0; i < LUA_NUMTAGS; i++)
304 markobject(g, g->mt[i]);
305}
#define LUA_NUMTAGS
struct Table * mt[NUM_TAGS]

References LUA_NUMTAGS, markobject, and global_State::mt.

Referenced by atomic(), and restartcollection().

◆ propagateall()

static void propagateall ( global_State * g)
static

Definition at line 566 of file lua-5.2.4/src/lgc.c.

566 {
567 while (g->gray) propagatemark(g);
568}
static void propagatemark(global_State *g)

References global_State::gray, and propagatemark().

Referenced by atomic(), convergeephemerons(), propagatelist(), and retraversegrays().

◆ propagatelist()

static void propagatelist ( global_State * g,
GCObject * l )
static

Definition at line 571 of file lua-5.2.4/src/lgc.c.

571 {
572 lua_assert(g->gray == NULL); /* no grays left */
573 g->gray = l;
574 propagateall(g); /* traverse all elements from 'l' */
575}

References global_State::gray, lua_assert, NULL, and propagateall().

Referenced by retraversegrays().

◆ propagatemark()

static void propagatemark ( global_State * g)
static

Definition at line 521 of file lua-5.2.4/src/lgc.c.

521 {
522 lu_mem size;
523 GCObject *o = g->gray;
524 lua_assert(isgray(o));
525 gray2black(o);
526 switch (gch(o)->tt) {
527 case LUA_TTABLE: {
528 Table *h = gco2t(o);
529 g->gray = h->gclist; /* remove from 'gray' list */
530 size = traversetable(g, h);
531 break;
532 }
533 case LUA_TLCL: {
534 LClosure *cl = gco2lcl(o);
535 g->gray = cl->gclist; /* remove from 'gray' list */
536 size = traverseLclosure(g, cl);
537 break;
538 }
539 case LUA_TCCL: {
540 CClosure *cl = gco2ccl(o);
541 g->gray = cl->gclist; /* remove from 'gray' list */
542 size = traverseCclosure(g, cl);
543 break;
544 }
545 case LUA_TTHREAD: {
546 lua_State *th = gco2th(o);
547 g->gray = th->gclist; /* remove from 'gray' list */
548 th->gclist = g->grayagain;
549 g->grayagain = o; /* insert into 'grayagain' list */
550 black2gray(o);
551 size = traversestack(g, th);
552 break;
553 }
554 case LUA_TPROTO: {
555 Proto *p = gco2p(o);
556 g->gray = p->gclist; /* remove from 'gray' list */
557 size = traverseproto(g, p);
558 break;
559 }
560 default: lua_assert(0); return;
561 }
562 g->GCmemtrav += size;
563}
static int traverseproto(global_State *g, Proto *f)
static lu_mem traverseLclosure(global_State *g, LClosure *cl)
static lu_mem traversetable(global_State *g, Table *h)
static lu_mem traverseCclosure(global_State *g, CClosure *cl)
static lu_mem traversestack(global_State *g, lua_State *th)
GCObject * gclist

References black2gray, gch, Proto::gclist, Table::gclist, lua_State::gclist, global_State::GCmemtrav, gco2ccl, gco2lcl, gco2p, gco2t, gco2th, global_State::gray, gray2black, global_State::grayagain, isgray, lua_assert, LUA_TCCL, LUA_TLCL, LUA_TPROTO, LUA_TTABLE, LUA_TTHREAD, traverseCclosure(), traverseLclosure(), traverseproto(), traversestack(), and traversetable().

Referenced by propagateall(), and singlestep().

◆ reallymarkobject()

static void reallymarkobject ( global_State * g,
GCObject * o )
static

Definition at line 243 of file lua-5.2.4/src/lgc.c.

243 {
244 lu_mem size;
245 white2gray(o);
246 switch (gch(o)->tt) {
247 case LUA_TSHRSTR:
248 case LUA_TLNGSTR: {
249 size = sizestring(gco2ts(o));
250 break; /* nothing else to mark; make it black */
251 }
252 case LUA_TUSERDATA: {
253 Table *mt = gco2u(o)->metatable;
254 markobject(g, mt);
255 markobject(g, gco2u(o)->env);
256 size = sizeudata(gco2u(o));
257 break;
258 }
259 case LUA_TUPVAL: {
260 UpVal *uv = gco2uv(o);
261 markvalue(g, uv->v);
262 if (uv->v != &uv->u.value) /* open? */
263 return; /* open upvalues remain gray */
264 size = sizeof(UpVal);
265 break;
266 }
267 case LUA_TLCL: {
268 gco2lcl(o)->gclist = g->gray;
269 g->gray = o;
270 return;
271 }
272 case LUA_TCCL: {
273 gco2ccl(o)->gclist = g->gray;
274 g->gray = o;
275 return;
276 }
277 case LUA_TTABLE: {
278 linktable(gco2t(o), &g->gray);
279 return;
280 }
281 case LUA_TTHREAD: {
282 gco2th(o)->gclist = g->gray;
283 g->gray = o;
284 return;
285 }
286 case LUA_TPROTO: {
287 gco2p(o)->gclist = g->gray;
288 g->gray = o;
289 return;
290 }
291 default: lua_assert(0); return;
292 }
293 gray2black(o);
294 g->GCmemtrav += size;
295}
struct UpVal UpVal
#define white2gray(x)
#define linktable(h, p)
struct Table * metatable
union UpVal::@48 u

References gch, global_State::GCmemtrav, gco2ccl, gco2lcl, gco2p, gco2t, gco2th, gco2ts, gco2u, gco2uv, global_State::gray, gray2black, linktable, lua_assert, LUA_TCCL, LUA_TLCL, LUA_TLNGSTR, LUA_TPROTO, LUA_TSHRSTR, LUA_TTABLE, LUA_TTHREAD, LUA_TUPVAL, LUA_TUSERDATA, markobject, markvalue, Table::metatable, sizestring, sizeudata, UpVal::u, UpVal::v, UpVal::value, and white2gray.

Referenced by luaC_barrier_(), markbeingfnz(), and traverseephemeron().

◆ remarkupvals()

static void remarkupvals ( global_State * g)
static

Definition at line 324 of file lua-5.2.4/src/lgc.c.

324 {
325 UpVal *uv;
326 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
327 if (isgray(obj2gco(uv)))
328 markvalue(g, uv->v);
329 }
330}
struct UpVal * next
struct UpVal::@48::@49 l

References isgray, UpVal::l, markvalue, UpVal::next, obj2gco, UpVal::u, global_State::uvhead, and UpVal::v.

Referenced by atomic().

◆ removeentry()

static void removeentry ( Node * n)
static

Definition at line 107 of file lua-5.2.4/src/lgc.c.

107 {
109 if (valiswhite(gkey(n)))
110 setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */
111}
#define setdeadvalue(obj)

References gkey, gval, lua_assert, setdeadvalue, ttisnil, and valiswhite.

Referenced by clearkeys(), clearvalues(), traverseephemeron(), traversestrongtable(), and traverseweakvalue().

◆ restartcollection()

static void restartcollection ( global_State * g)
static

Definition at line 337 of file lua-5.2.4/src/lgc.c.

337 {
338 g->gray = g->grayagain = NULL;
339 g->weak = g->allweak = g->ephemeron = NULL;
340 markobject(g, g->mainthread);
341 markvalue(g, &g->l_registry);
342 markmt(g);
343 markbeingfnz(g); /* mark any finalizing object left from previous cycle */
344}

References global_State::allweak, global_State::ephemeron, global_State::gray, global_State::grayagain, global_State::l_registry, global_State::mainthread, markbeingfnz(), markmt(), markobject, markvalue, NULL, and global_State::weak.

Referenced by singlestep().

◆ retraversegrays()

static void retraversegrays ( global_State * g)
static

Definition at line 582 of file lua-5.2.4/src/lgc.c.

582 {
583 GCObject *weak = g->weak; /* save original lists */
584 GCObject *grayagain = g->grayagain;
585 GCObject *ephemeron = g->ephemeron;
586 g->weak = g->grayagain = g->ephemeron = NULL;
587 propagateall(g); /* traverse main gray list */
588 propagatelist(g, grayagain);
589 propagatelist(g, weak);
590 propagatelist(g, ephemeron);
591}
static void propagatelist(global_State *g, GCObject *l)

References global_State::ephemeron, global_State::grayagain, NULL, propagateall(), propagatelist(), and global_State::weak.

Referenced by atomic().

◆ separatetobefnz()

static void separatetobefnz ( lua_State * L,
int all )
static

Definition at line 845 of file lua-5.2.4/src/lgc.c.

845 {
846 global_State *g = G(L);
847 GCObject **p = &g->finobj;
848 GCObject *curr;
849 GCObject **lastnext = &g->tobefnz;
850 /* find last 'next' field in 'tobefnz' list (to add elements in its end) */
851 while (*lastnext != NULL)
852 lastnext = &gch(*lastnext)->next;
853 while ((curr = *p) != NULL) { /* traverse all finalizable objects */
854 lua_assert(!isfinalized(curr));
855 lua_assert(testbit(gch(curr)->marked, SEPARATED));
856 if (!(iswhite(curr) || all)) /* not being collected? */
857 p = &gch(curr)->next; /* don't bother with it */
858 else {
859 l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
860 *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */
861 gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */
862 *lastnext = curr;
863 lastnext = &gch(curr)->next;
864 }
865 }
866}
#define FINALIZEDBIT

References FINALIZEDBIT, global_State::finobj, G, gch, isfinalized, iswhite, l_setbit, lua_assert, NULL, SEPARATED, testbit, and global_State::tobefnz.

Referenced by atomic(), and luaC_freeallobjects().

◆ setpause()

static void setpause ( global_State * g,
l_mem estimate )
static

Definition at line 913 of file lua-5.2.4/src/lgc.c.

913 {
914 l_mem debt, threshold;
915 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
916 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
917 ? estimate * g->gcpause /* no overflow */
918 : MAX_LMEM; /* overflow; truncate to maximum */
919 debt = -cast(l_mem, threshold - gettotalbytes(g));
920 luaE_setdebt(g, debt);
921}
#define PAUSEADJ

References cast, global_State::gcpause, gettotalbytes, luaE_setdebt(), MAX_LMEM, and PAUSEADJ.

Referenced by generationalcollection(), incstep(), and luaC_fullgc().

◆ singlestep()

static lu_mem singlestep ( lua_State * L)
static

Definition at line 1040 of file lua-5.2.4/src/lgc.c.

1040 {
1041 global_State *g = G(L);
1042 switch (g->gcstate) {
1043 case GCSpause: {
1044 /* start to count memory traversed */
1045 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1048 g->gcstate = GCSpropagate;
1049 return g->GCmemtrav;
1050 }
1051 case GCSpropagate: {
1052 if (g->gray) {
1053 lu_mem oldtrav = g->GCmemtrav;
1054 propagatemark(g);
1055 return g->GCmemtrav - oldtrav; /* memory traversed in this step */
1056 }
1057 else { /* no more `gray' objects */
1058 lu_mem work;
1059 int sw;
1060 g->gcstate = GCSatomic; /* finish mark phase */
1061 g->GCestimate = g->GCmemtrav; /* save what was counted */;
1062 work = atomic(L); /* add what was traversed by 'atomic' */
1063 g->GCestimate += work; /* estimate of total memory traversed */
1064 sw = entersweep(L);
1065 return work + sw * GCSWEEPCOST;
1066 }
1067 }
1068 case GCSsweepstring: {
1069 int i;
1070 for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)
1071 sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);
1072 g->sweepstrgc += i;
1073 if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */
1075 return i * GCSWEEPCOST;
1076 }
1077 case GCSsweepudata: {
1078 if (g->sweepfin) {
1080 return GCSWEEPMAX*GCSWEEPCOST;
1081 }
1082 else {
1083 g->gcstate = GCSsweep;
1084 return 0;
1085 }
1086 }
1087 case GCSsweep: {
1088 if (g->sweepgc) {
1089 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1090 return GCSWEEPMAX*GCSWEEPCOST;
1091 }
1092 else {
1093 /* sweep main thread */
1094 GCObject *mt = obj2gco(g->mainthread);
1095 sweeplist(L, &mt, 1);
1096 checkSizes(L);
1097 g->gcstate = GCSpause; /* finish collection */
1098 return GCSWEEPCOST;
1099 }
1100 }
1101 default: lua_assert(0); return 0;
1102 }
1103}
#define GCSsweep
static void checkSizes(lua_State *L)
static GCObject ** sweeplist(lua_State *L, GCObject **p, lu_mem count)
static void restartcollection(global_State *g)
#define GCSWEEPMAX
#define GCSWEEPCOST
static l_mem atomic(lua_State *L)
#define GCSsweepudata
#define GCSatomic

References atomic(), checkSizes(), entersweep(), G, global_State::GCestimate, global_State::GCmemtrav, GCSatomic, GCSpause, GCSpropagate, GCSsweep, GCSsweepstring, GCSsweepudata, global_State::gcstate, GCSWEEPCOST, GCSWEEPMAX, global_State::gray, stringtable::hash, isgenerational, lua_assert, global_State::mainthread, obj2gco, propagatemark(), restartcollection(), stringtable::size, global_State::strt, global_State::sweepfin, global_State::sweepgc, sweeplist(), global_State::sweepstrgc, and sweepwholelist.

Referenced by incstep(), and luaC_runtilstate().

◆ sweeplist()

static GCObject ** sweeplist ( lua_State * L,
GCObject ** p,
lu_mem count )
static

Definition at line 719 of file lua-5.2.4/src/lgc.c.

719 {
720 global_State *g = G(L);
721 int ow = otherwhite(g);
722 int toclear, toset; /* bits to clear and to set in all live objects */
723 int tostop; /* stop sweep when this is true */
724 if (isgenerational(g)) { /* generational mode? */
725 toclear = ~0; /* clear nothing */
726 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
727 tostop = bitmask(OLDBIT); /* do not sweep old generation */
728 }
729 else { /* normal mode */
730 toclear = maskcolors; /* clear all color bits + old bit */
731 toset = luaC_white(g); /* make object white */
732 tostop = 0; /* do not stop */
733 }
734 while (*p != NULL && count-- > 0) {
735 GCObject *curr = *p;
736 int marked = gch(curr)->marked;
737 if (isdeadm(ow, marked)) { /* is 'curr' dead? */
738 *p = gch(curr)->next; /* remove 'curr' from list */
739 freeobj(L, curr); /* erase 'curr' */
740 }
741 else {
742 if (testbits(marked, tostop))
743 return NULL; /* stop sweeping this list */
744 if (gch(curr)->tt == LUA_TTHREAD)
745 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
746 /* update marks */
747 gch(curr)->marked = cast_byte((marked & toclear) | toset);
748 p = &gch(curr)->next; /* go to next element */
749 }
750 }
751 return (*p == NULL) ? NULL : p;
752}
#define testbits(x, m)
#define maskcolors
static void sweepthread(lua_State *L, lua_State *L1)
static void freeobj(lua_State *L, GCObject *o)
#define isdeadm(ow, m)
#define OLDBIT

References bitmask, cast_byte, freeobj(), G, gch, gco2th, isdeadm, isgenerational, LUA_TTHREAD, luaC_white, maskcolors, NULL, OLDBIT, otherwhite, sweepthread(), and testbits.

Referenced by singlestep(), and sweeptolive().

◆ sweepthread()

static void sweepthread ( lua_State * L,
lua_State * L1 )
static

Definition at line 698 of file lua-5.2.4/src/lgc.c.

698 {
699 if (L1->stack == NULL) return; /* stack not completely built yet */
700 sweepwholelist(L, &L1->openupval); /* sweep open upvalues */
701 luaE_freeCI(L1); /* free extra CallInfo slots */
702 /* should not change the stack during an emergency gc cycle */
703 if (G(L)->gckind != KGC_EMERGENCY)
705}
void luaD_shrinkstack(lua_State *L)
void luaE_freeCI(lua_State *L)
GCObject * openupval

References G, KGC_EMERGENCY, luaD_shrinkstack(), luaE_freeCI(), NULL, lua_State::openupval, lua_State::stack, and sweepwholelist.

Referenced by sweeplist().

◆ sweeptolive()

static GCObject ** sweeptolive ( lua_State * L,
GCObject ** p,
int * n )
static

Definition at line 758 of file lua-5.2.4/src/lgc.c.

758 {
759 GCObject ** old = p;
760 int i = 0;
761 do {
762 i++;
763 p = sweeplist(L, p, 1);
764 } while (p == old);
765 if (n) *n += i;
766 return p;
767}

References sweeplist().

Referenced by entersweep(), and luaC_checkfinalizer().

◆ traverseCclosure()

static lu_mem traverseCclosure ( global_State * g,
CClosure * cl )
static

Definition at line 479 of file lua-5.2.4/src/lgc.c.

479 {
480 int i;
481 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
482 markvalue(g, &cl->upvalue[i]);
483 return sizeCclosure(cl->nupvalues);
484}

References markvalue, sizeCclosure, and CClosure::upvalue.

Referenced by propagatemark().

◆ traverseephemeron()

static int traverseephemeron ( global_State * g,
Table * h )
static

Definition at line 378 of file lua-5.2.4/src/lgc.c.

378 {
379 int marked = 0; /* true if an object is marked in this traversal */
380 int hasclears = 0; /* true if table has white keys */
381 int prop = 0; /* true if table has entry "white-key -> white-value" */
382 Node *n, *limit = gnodelast(h);
383 int i;
384 /* traverse array part (numeric keys are 'strong') */
385 for (i = 0; i < h->sizearray; i++) {
386 if (valiswhite(&h->array[i])) {
387 marked = 1;
388 reallymarkobject(g, gcvalue(&h->array[i]));
389 }
390 }
391 /* traverse hash part */
392 for (n = gnode(h, 0); n < limit; n++) {
393 checkdeadkey(n);
394 if (ttisnil(gval(n))) /* entry is empty? */
395 removeentry(n); /* remove it */
396 else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */
397 hasclears = 1; /* table must be cleared */
398 if (valiswhite(gval(n))) /* value not marked yet? */
399 prop = 1; /* must propagate again */
400 }
401 else if (valiswhite(gval(n))) { /* value not marked yet? */
402 marked = 1;
403 reallymarkobject(g, gcvalue(gval(n))); /* mark it now */
404 }
405 }
406 if (g->gcstate != GCSatomic || prop)
407 linktable(h, &g->ephemeron); /* have to propagate again */
408 else if (hasclears) /* does table have white keys? */
409 linktable(h, &g->allweak); /* may have to clean white keys */
410 else /* no white keys */
411 linktable(h, &g->grayagain); /* no need to clean */
412 return marked;
413}
#define checkdeadkey(n)

References global_State::allweak, Table::array, checkdeadkey, global_State::ephemeron, GCSatomic, global_State::gcstate, gcvalue, gkey, gnode, gnodelast, global_State::grayagain, gval, iscleared(), linktable, reallymarkobject(), removeentry(), Table::sizearray, ttisnil, and valiswhite.

Referenced by convergeephemerons(), and traversetable().

◆ traverseLclosure()

static lu_mem traverseLclosure ( global_State * g,
LClosure * cl )
static

Definition at line 486 of file lua-5.2.4/src/lgc.c.

486 {
487 int i;
488 markobject(g, cl->p); /* mark its prototype */
489 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */
490 markobject(g, cl->upvals[i]);
491 return sizeLclosure(cl->nupvalues);
492}
struct Proto * p

References markobject, LClosure::p, sizeLclosure, and LClosure::upvals.

Referenced by propagatemark().

◆ traverseproto()

static int traverseproto ( global_State * g,
Proto * f )
static

Definition at line 457 of file lua-5.2.4/src/lgc.c.

457 {
458 int i;
459 if (f->cache && iswhite(obj2gco(f->cache)))
460 f->cache = NULL; /* allow cache to be collected */
461 markobject(g, f->source);
462 for (i = 0; i < f->sizek; i++) /* mark literals */
463 markvalue(g, &f->k[i]);
464 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
465 markobject(g, f->upvalues[i].name);
466 for (i = 0; i < f->sizep; i++) /* mark nested protos */
467 markobject(g, f->p[i]);
468 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
469 markobject(g, f->locvars[i].varname);
470 return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
471 sizeof(Proto *) * f->sizep +
472 sizeof(TValue) * f->sizek +
473 sizeof(int) * f->sizelineinfo +
474 sizeof(LocVar) * f->sizelocvars +
475 sizeof(Upvaldesc) * f->sizeupvalues;
476}
lu_int32 Instruction
struct Proto Proto
struct Upvaldesc Upvaldesc
TString * varname
struct LocVar * locvars
struct Proto ** p
TString ** upvalues
TString * source

References Proto::cache, iswhite, Proto::k, Proto::locvars, markobject, markvalue, NULL, obj2gco, Proto::p, Proto::sizecode, Proto::sizek, Proto::sizelineinfo, Proto::sizelocvars, Proto::sizep, Proto::sizeupvalues, Proto::source, Proto::upvalues, and LocVar::varname.

Referenced by propagatemark().

◆ traversestack()

static lu_mem traversestack ( global_State * g,
lua_State * th )
static

Definition at line 495 of file lua-5.2.4/src/lgc.c.

495 {
496 int n = 0;
497 StkId o = th->stack;
498 if (o == NULL)
499 return 1; /* stack not completely built yet */
500 for (; o < th->top; o++) /* mark live elements in the stack */
501 markvalue(g, o);
502 if (g->gcstate == GCSatomic) { /* final traversal? */
503 StkId lim = th->stack + th->stacksize; /* real end of stack */
504 for (; o < lim; o++) /* clear not-marked stack slice */
505 setnilvalue(o);
506 }
507 else { /* count call infos to compute size */
508 CallInfo *ci;
509 for (ci = &th->base_ci; ci != th->ci; ci = ci->next)
510 n++;
511 }
512 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
513 sizeof(CallInfo) * n;
514}
struct CallInfo CallInfo
struct lua_State lua_State
struct CallInfo * next

References lua_State::base_ci, lua_State::ci, GCSatomic, global_State::gcstate, markvalue, CallInfo::next, NULL, setnilvalue, lua_State::stack, lua_State::stacksize, and lua_State::top.

Referenced by propagatemark().

◆ traversestrongtable()

static void traversestrongtable ( global_State * g,
Table * h )
static

Definition at line 416 of file lua-5.2.4/src/lgc.c.

416 {
417 Node *n, *limit = gnodelast(h);
418 int i;
419 for (i = 0; i < h->sizearray; i++) /* traverse array part */
420 markvalue(g, &h->array[i]);
421 for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */
422 checkdeadkey(n);
423 if (ttisnil(gval(n))) /* entry is empty? */
424 removeentry(n); /* remove it */
425 else {
426 lua_assert(!ttisnil(gkey(n)));
427 markvalue(g, gkey(n)); /* mark key */
428 markvalue(g, gval(n)); /* mark value */
429 }
430 }
431}

References Table::array, checkdeadkey, gkey, gnode, gnodelast, gval, lua_assert, markvalue, removeentry(), Table::sizearray, and ttisnil.

Referenced by traversetable().

◆ traversetable()

static lu_mem traversetable ( global_State * g,
Table * h )
static

Definition at line 434 of file lua-5.2.4/src/lgc.c.

434 {
435 const char *weakkey, *weakvalue;
436 const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
437 markobject(g, h->metatable);
438 if (mode && ttisstring(mode) && /* is there a weak mode? */
439 ((weakkey = strchr(svalue(mode), 'k')),
440 (weakvalue = strchr(svalue(mode), 'v')),
441 (weakkey || weakvalue))) { /* is really weak? */
442 black2gray(obj2gco(h)); /* keep table gray */
443 if (!weakkey) /* strong keys? */
444 traverseweakvalue(g, h);
445 else if (!weakvalue) /* strong values? */
446 traverseephemeron(g, h);
447 else /* all weak */
448 linktable(h, &g->allweak); /* nothing to traverse now */
449 }
450 else /* not weak */
452 return sizeof(Table) + sizeof(TValue) * h->sizearray +
453 sizeof(Node) * cast(size_t, sizenode(h));
454}
#define sizenode(t)
struct Node Node
struct Table Table
@ TM_MODE
static void traversestrongtable(global_State *g, Table *h)
static void traverseweakvalue(global_State *g, Table *h)

References global_State::allweak, black2gray, cast, gfasttm, linktable, markobject, Table::metatable, obj2gco, Table::sizearray, sizenode, svalue, TM_MODE, traverseephemeron(), traversestrongtable(), traverseweakvalue(), and ttisstring.

Referenced by propagatemark().

◆ traverseweakvalue()

static void traverseweakvalue ( global_State * g,
Table * h )
static

Definition at line 355 of file lua-5.2.4/src/lgc.c.

355 {
356 Node *n, *limit = gnodelast(h);
357 /* if there is array part, assume it may have white values (do not
358 traverse it just to check) */
359 int hasclears = (h->sizearray > 0);
360 for (n = gnode(h, 0); n < limit; n++) {
361 checkdeadkey(n);
362 if (ttisnil(gval(n))) /* entry is empty? */
363 removeentry(n); /* remove it */
364 else {
365 lua_assert(!ttisnil(gkey(n)));
366 markvalue(g, gkey(n)); /* mark key */
367 if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */
368 hasclears = 1; /* table will have to be cleared */
369 }
370 }
371 if (hasclears)
372 linktable(h, &g->weak); /* has to be cleared later */
373 else /* no white values */
374 linktable(h, &g->grayagain); /* no need to clean */
375}

References checkdeadkey, gkey, gnode, gnodelast, global_State::grayagain, gval, iscleared(), linktable, lua_assert, markvalue, removeentry(), Table::sizearray, ttisnil, and global_State::weak.

Referenced by traversetable().

◆ udata2finalize()

static GCObject * udata2finalize ( global_State * g)
static

Definition at line 789 of file lua-5.2.4/src/lgc.c.

789 {
790 GCObject *o = g->tobefnz; /* get first element */
792 g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */
793 gch(o)->next = g->allgc; /* return it to 'allgc' list */
794 g->allgc = o;
795 resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */
796 lua_assert(!isold(o)); /* see MOVE OLD rule */
797 if (!keepinvariantout(g)) /* not keeping invariant? */
798 makewhite(g, o); /* "sweep" object */
799 return o;
800}
#define resetbit(x, b)
#define isold(x)

References global_State::allgc, gch, isfinalized, isold, keepinvariantout, lua_assert, makewhite, resetbit, SEPARATED, and global_State::tobefnz.

Referenced by GCTM().