summaryrefslogtreecommitdiffstats
path: root/apps/plugins/lua/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/lgc.c')
-rw-r--r--apps/plugins/lua/lgc.c60
1 files changed, 49 insertions, 11 deletions
diff --git a/apps/plugins/lua/lgc.c b/apps/plugins/lua/lgc.c
index 98194c1771..17b64a103b 100644
--- a/apps/plugins/lua/lgc.c
+++ b/apps/plugins/lua/lgc.c
@@ -58,6 +58,9 @@
#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
+#ifndef yield
+ #define yield() {}
+#endif
static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
@@ -232,8 +235,10 @@ static void traverseclosure (global_State *g, Closure *cl) {
int i;
lua_assert(cl->l.nupvalues == cl->l.p->nups);
markobject(g, cl->l.p);
- for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */
- markobject(g, cl->l.upvals[i]);
+ for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
+ if(cl->l.upvals[i])
+ markobject(g, cl->l.upvals[i]);
+ }
}
}
@@ -258,6 +263,7 @@ static void traversestack (global_State *g, lua_State *l) {
CallInfo *ci;
markvalue(g, gt(l));
lim = l->top;
+ if(l->stack == NULL) return; /* no stack to traverse */
for (ci = l->base_ci; ci <= l->ci; ci++) {
lua_assert(ci->top <= l->stack_last);
if (lim < ci->top) lim = ci->top;
@@ -266,7 +272,8 @@ static void traversestack (global_State *g, lua_State *l) {
markvalue(g, o);
for (; o <= lim; o++)
setnilvalue(o);
- checkstacksizes(l, lim);
+ if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */
+ checkstacksizes(l, lim);
}
@@ -419,8 +426,6 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
else { /* must erase `curr' */
lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
*p = curr->gch.next;
- if (curr == g->rootgc) /* is the first element of the list? */
- g->rootgc = curr->gch.next; /* adjust first */
freeobj(L, curr);
}
}
@@ -434,6 +439,8 @@ static void checkSizes (lua_State *L) {
if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
g->strt.size > MINSTRTABSIZE*2)
luaS_resize(L, g->strt.size/2); /* table is too big */
+ /* it is not safe to re-size the buffer if it is in use. */
+ if (luaZ_bufflen(&g->buff) > 0) return;
/* check size of buffer */
if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
@@ -552,6 +559,15 @@ static void atomic (lua_State *L) {
g->estimate = g->totalbytes - udsize; /* first estimate */
}
+static void sweepstrstep (global_State *g, lua_State *L) {
+ lu_mem old = g->totalbytes;
+ sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
+ if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
+ g->gcstate = GCSsweep; /* end sweep-string phase */
+ lua_assert(old >= g->totalbytes);
+ g->estimate -= old - g->totalbytes;
+}
+
static l_mem singlestep (lua_State *L) {
global_State *g = G(L);
@@ -570,12 +586,7 @@ static l_mem singlestep (lua_State *L) {
}
}
case GCSsweepstring: {
- lu_mem old = g->totalbytes;
- sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
- if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
- g->gcstate = GCSsweep; /* end sweep-string phase */
- lua_assert(old >= g->totalbytes);
- g->estimate -= old - g->totalbytes;
+ sweepstrstep(g, L);
return GCSWEEPCOST;
}
case GCSsweep: {
@@ -609,10 +620,14 @@ static l_mem singlestep (lua_State *L) {
void luaC_step (lua_State *L) {
global_State *g = G(L);
+ if(is_block_gc(L)) return;
+ set_block_gc(L);
l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
if (lim == 0)
lim = (MAX_LUMEM-1)/2; /* no limit */
g->gcdept += g->totalbytes - g->GCthreshold;
+ if (g->estimate > g->totalbytes)
+ g->estimate = g->totalbytes;
do {
lim -= singlestep(L);
if (g->gcstate == GCSpause)
@@ -629,11 +644,23 @@ void luaC_step (lua_State *L) {
else {
setthreshold(g);
}
+ unset_block_gc(L);
}
+int luaC_sweepstrgc (lua_State *L) {
+ global_State *g = G(L);
+ if (g->gcstate == GCSsweepstring) {
+ sweepstrstep(g, L);
+ return (g->gcstate == GCSsweepstring) ? 1 : 0;
+ }
+ return 0;
+}
+
void luaC_fullgc (lua_State *L) {
global_State *g = G(L);
+ if(is_block_gc(L)) return;
+ set_block_gc(L);
if (g->gcstate <= GCSpropagate) {
/* reset sweep marks to sweep all elements (returning them to white) */
g->sweepstrgc = 0;
@@ -649,12 +676,15 @@ void luaC_fullgc (lua_State *L) {
while (g->gcstate != GCSfinalize) {
lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
singlestep(L);
+ yield();
}
markroot(L);
while (g->gcstate != GCSpause) {
singlestep(L);
+ yield();
}
setthreshold(g);
+ unset_block_gc(L);
}
@@ -682,6 +712,14 @@ void luaC_barrierback (lua_State *L, Table *t) {
}
+void luaC_marknew (lua_State *L, GCObject *o) {
+ global_State *g = G(L);
+ o->gch.marked = luaC_white(g);
+ if (g->gcstate == GCSpropagate)
+ reallymarkobject(g, o); /* mark new objects as gray during propagate state. */
+}
+
+
void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
global_State *g = G(L);
o->gch.next = g->rootgc;