Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/extern/lua/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/extern/lua/lgc.c')
-rw-r--r--source/extern/lua/lgc.c70
1 files changed, 37 insertions, 33 deletions
diff --git a/source/extern/lua/lgc.c b/source/extern/lua/lgc.c
index 973c269..db4df82 100644
--- a/source/extern/lua/lgc.c
+++ b/source/extern/lua/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.205 2015/03/25 13:42:19 roberto Exp $
+** $Id: lgc.c,v 2.215.1.2 2017/08/31 16:15:27 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -114,8 +114,13 @@ static void reallymarkobject (global_State *g, GCObject *o);
/*
-** if key is not marked, mark its entry as dead (therefore removing it
-** from the table)
+** If key is not marked, mark its entry as dead. This allows key to be
+** collected, but keeps its entry in the table. A dead node is needed
+** when Lua looks up for a key (it may be part of a chain) and when
+** traversing a weak table (key might be removed from the table during
+** traversal). Other places never manipulate dead keys, because its
+** associated nil value is enough to signal that the entry is logically
+** empty.
*/
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
@@ -462,7 +467,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
else /* not weak */
traversestrongtable(g, h);
return sizeof(Table) + sizeof(TValue) * h->sizearray +
- sizeof(Node) * cast(size_t, sizenode(h));
+ sizeof(Node) * cast(size_t, allocsizenode(h));
}
@@ -534,7 +539,7 @@ static lu_mem traversethread (global_State *g, lua_State *th) {
StkId lim = th->stack + th->stacksize; /* real end of stack */
for (; o < lim; o++) /* clear not-marked stack slice */
setnilvalue(o);
- /* 'remarkupvals' may have removed thread from 'twups' list */
+ /* 'remarkupvals' may have removed thread from 'twups' list */
if (!isintwups(th) && th->openupval != NULL) {
th->twups = g->twups; /* link it back to the list */
g->twups = th;
@@ -542,7 +547,8 @@ static lu_mem traversethread (global_State *g, lua_State *th) {
}
else if (g->gckind != KGC_EMERGENCY)
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
- return (sizeof(lua_State) + sizeof(TValue) * th->stacksize);
+ return (sizeof(lua_State) + sizeof(TValue) * th->stacksize +
+ sizeof(CallInfo) * th->nci);
}
@@ -637,8 +643,9 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
for (n = gnode(h, 0); n < limit; n++) {
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
setnilvalue(gval(n)); /* remove value ... */
- removeentry(n); /* and remove entry from table */
}
+ if (ttisnil(gval(n))) /* is entry empty? */
+ removeentry(n); /* remove entry from table */
}
}
}
@@ -748,14 +755,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
/*
** sweep a list until a live object (or end of list)
*/
-static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
+static GCObject **sweeptolive (lua_State *L, GCObject **p) {
GCObject **old = p;
- int i = 0;
do {
- i++;
p = sweeplist(L, p, 1);
} while (p == old);
- if (n) *n += i;
return p;
}
@@ -769,12 +773,11 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
*/
/*
-** If possible, free concatenation buffer and shrink string table
+** If possible, shrink string table
*/
static void checkSizes (lua_State *L, global_State *g) {
if (g->gckind != KGC_EMERGENCY) {
l_mem olddebt = g->GCdebt;
- luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
luaS_resize(L, g->strt.size / 2); /* shrink it a little */
g->GCestimate += g->GCdebt - olddebt; /* update estimate */
@@ -797,7 +800,7 @@ static GCObject *udata2finalize (global_State *g) {
static void dothecall (lua_State *L, void *ud) {
UNUSED(ud);
- luaD_call(L, L->top - 2, 0, 0);
+ luaD_callnoyield(L, L->top - 2, 0);
}
@@ -816,7 +819,9 @@ static void GCTM (lua_State *L, int propagateerrors) {
setobj2s(L, L->top, tm); /* push finalizer... */
setobj2s(L, L->top + 1, &v); /* ... and its argument */
L->top += 2; /* and (next line) call the finalizer */
+ L->ci->callstatus |= CIST_FIN; /* will run a finalizer */
status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
+ L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */
L->allowhook = oldah; /* restore hooks */
g->gcrunning = running; /* restore state */
if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
@@ -851,10 +856,10 @@ static int runafewfinalizers (lua_State *L) {
/*
** call all pending finalizers
*/
-static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
+static void callallpendingfinalizers (lua_State *L) {
global_State *g = G(L);
while (g->tobefnz)
- GCTM(L, propagateerrors);
+ GCTM(L, 0);
}
@@ -904,7 +909,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
if (issweepphase(g)) {
makewhite(g, o); /* "sweep" object 'o' */
if (g->sweepgc == &o->next) /* should not remove 'sweepgc' object */
- g->sweepgc = sweeptolive(L, g->sweepgc, NULL); /* change 'sweepgc' */
+ g->sweepgc = sweeptolive(L, g->sweepgc); /* change 'sweepgc' */
}
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &(*p)->next) { /* empty */ }
@@ -946,19 +951,16 @@ static void setpause (global_State *g) {
/*
** Enter first sweep phase.
-** The call to 'sweeptolive' makes pointer point to an object inside
-** the list (instead of to the header), so that the real sweep do not
-** need to skip objects created between "now" and the start of the real
-** sweep.
-** Returns how many objects it swept.
+** The call to 'sweeplist' tries to make pointer point to an object
+** inside the list (instead of to the header), so that the real sweep do
+** not need to skip objects created between "now" and the start of the
+** real sweep.
*/
-static int entersweep (lua_State *L) {
+static void entersweep (lua_State *L) {
global_State *g = G(L);
- int n = 0;
g->gcstate = GCSswpallgc;
lua_assert(g->sweepgc == NULL);
- g->sweepgc = sweeptolive(L, &g->allgc, &n);
- return n;
+ g->sweepgc = sweeplist(L, &g->allgc, 1);
}
@@ -966,7 +968,7 @@ void luaC_freeallobjects (lua_State *L) {
global_State *g = G(L);
separatetobefnz(g, 1); /* separate all objects with finalizers */
lua_assert(g->finobj == NULL);
- callallpendingfinalizers(L, 0);
+ callallpendingfinalizers(L);
lua_assert(g->tobefnz == NULL);
g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
g->gckind = KGC_NORMAL;
@@ -1059,12 +1061,11 @@ static lu_mem singlestep (lua_State *L) {
}
case GCSatomic: {
lu_mem work;
- int sw;
propagateall(g); /* make sure gray list is empty */
work = atomic(L); /* work is what was traversed by 'atomic' */
- sw = entersweep(L);
+ entersweep(L);
g->GCestimate = gettotalbytes(g); /* first estimate */;
- return work + sw * GCSWEEPCOST;
+ return work;
}
case GCSswpallgc: { /* sweep "regular" objects */
return sweepstep(L, g, GCSswpfinobj, &g->finobj);
@@ -1114,9 +1115,12 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
static l_mem getdebt (global_State *g) {
l_mem debt = g->GCdebt;
int stepmul = g->gcstepmul;
- debt = (debt / STEPMULADJ) + 1;
- debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
- return debt;
+ if (debt <= 0) return 0; /* minimal debt */
+ else {
+ debt = (debt / STEPMULADJ) + 1;
+ debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
+ return debt;
+ }
}
/*