summaryrefslogtreecommitdiff
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 @@
58 58
59#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) 59#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause)
60 60
61#ifndef yield
62 #define yield() {}
63#endif
61 64
62static void removeentry (Node *n) { 65static void removeentry (Node *n) {
63 lua_assert(ttisnil(gval(n))); 66 lua_assert(ttisnil(gval(n)));
@@ -232,8 +235,10 @@ static void traverseclosure (global_State *g, Closure *cl) {
232 int i; 235 int i;
233 lua_assert(cl->l.nupvalues == cl->l.p->nups); 236 lua_assert(cl->l.nupvalues == cl->l.p->nups);
234 markobject(g, cl->l.p); 237 markobject(g, cl->l.p);
235 for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ 238 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
236 markobject(g, cl->l.upvals[i]); 239 if(cl->l.upvals[i])
240 markobject(g, cl->l.upvals[i]);
241 }
237 } 242 }
238} 243}
239 244
@@ -258,6 +263,7 @@ static void traversestack (global_State *g, lua_State *l) {
258 CallInfo *ci; 263 CallInfo *ci;
259 markvalue(g, gt(l)); 264 markvalue(g, gt(l));
260 lim = l->top; 265 lim = l->top;
266 if(l->stack == NULL) return; /* no stack to traverse */
261 for (ci = l->base_ci; ci <= l->ci; ci++) { 267 for (ci = l->base_ci; ci <= l->ci; ci++) {
262 lua_assert(ci->top <= l->stack_last); 268 lua_assert(ci->top <= l->stack_last);
263 if (lim < ci->top) lim = ci->top; 269 if (lim < ci->top) lim = ci->top;
@@ -266,7 +272,8 @@ static void traversestack (global_State *g, lua_State *l) {
266 markvalue(g, o); 272 markvalue(g, o);
267 for (; o <= lim; o++) 273 for (; o <= lim; o++)
268 setnilvalue(o); 274 setnilvalue(o);
269 checkstacksizes(l, lim); 275 if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */
276 checkstacksizes(l, lim);
270} 277}
271 278
272 279
@@ -419,8 +426,6 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
419 else { /* must erase `curr' */ 426 else { /* must erase `curr' */
420 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT)); 427 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
421 *p = curr->gch.next; 428 *p = curr->gch.next;
422 if (curr == g->rootgc) /* is the first element of the list? */
423 g->rootgc = curr->gch.next; /* adjust first */
424 freeobj(L, curr); 429 freeobj(L, curr);
425 } 430 }
426 } 431 }
@@ -434,6 +439,8 @@ static void checkSizes (lua_State *L) {
434 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && 439 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
435 g->strt.size > MINSTRTABSIZE*2) 440 g->strt.size > MINSTRTABSIZE*2)
436 luaS_resize(L, g->strt.size/2); /* table is too big */ 441 luaS_resize(L, g->strt.size/2); /* table is too big */
442 /* it is not safe to re-size the buffer if it is in use. */
443 if (luaZ_bufflen(&g->buff) > 0) return;
437 /* check size of buffer */ 444 /* check size of buffer */
438 if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ 445 if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */
439 size_t newsize = luaZ_sizebuffer(&g->buff) / 2; 446 size_t newsize = luaZ_sizebuffer(&g->buff) / 2;
@@ -552,6 +559,15 @@ static void atomic (lua_State *L) {
552 g->estimate = g->totalbytes - udsize; /* first estimate */ 559 g->estimate = g->totalbytes - udsize; /* first estimate */
553} 560}
554 561
562static void sweepstrstep (global_State *g, lua_State *L) {
563 lu_mem old = g->totalbytes;
564 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
565 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
566 g->gcstate = GCSsweep; /* end sweep-string phase */
567 lua_assert(old >= g->totalbytes);
568 g->estimate -= old - g->totalbytes;
569}
570
555 571
556static l_mem singlestep (lua_State *L) { 572static l_mem singlestep (lua_State *L) {
557 global_State *g = G(L); 573 global_State *g = G(L);
@@ -570,12 +586,7 @@ static l_mem singlestep (lua_State *L) {
570 } 586 }
571 } 587 }
572 case GCSsweepstring: { 588 case GCSsweepstring: {
573 lu_mem old = g->totalbytes; 589 sweepstrstep(g, L);
574 sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]);
575 if (g->sweepstrgc >= g->strt.size) /* nothing more to sweep? */
576 g->gcstate = GCSsweep; /* end sweep-string phase */
577 lua_assert(old >= g->totalbytes);
578 g->estimate -= old - g->totalbytes;
579 return GCSWEEPCOST; 590 return GCSWEEPCOST;
580 } 591 }
581 case GCSsweep: { 592 case GCSsweep: {
@@ -609,10 +620,14 @@ static l_mem singlestep (lua_State *L) {
609 620
610void luaC_step (lua_State *L) { 621void luaC_step (lua_State *L) {
611 global_State *g = G(L); 622 global_State *g = G(L);
623 if(is_block_gc(L)) return;
624 set_block_gc(L);
612 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; 625 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
613 if (lim == 0) 626 if (lim == 0)
614 lim = (MAX_LUMEM-1)/2; /* no limit */ 627 lim = (MAX_LUMEM-1)/2; /* no limit */
615 g->gcdept += g->totalbytes - g->GCthreshold; 628 g->gcdept += g->totalbytes - g->GCthreshold;
629 if (g->estimate > g->totalbytes)
630 g->estimate = g->totalbytes;
616 do { 631 do {
617 lim -= singlestep(L); 632 lim -= singlestep(L);
618 if (g->gcstate == GCSpause) 633 if (g->gcstate == GCSpause)
@@ -629,11 +644,23 @@ void luaC_step (lua_State *L) {
629 else { 644 else {
630 setthreshold(g); 645 setthreshold(g);
631 } 646 }
647 unset_block_gc(L);
632} 648}
633 649
634 650
651int luaC_sweepstrgc (lua_State *L) {
652 global_State *g = G(L);
653 if (g->gcstate == GCSsweepstring) {
654 sweepstrstep(g, L);
655 return (g->gcstate == GCSsweepstring) ? 1 : 0;
656 }
657 return 0;
658}
659
635void luaC_fullgc (lua_State *L) { 660void luaC_fullgc (lua_State *L) {
636 global_State *g = G(L); 661 global_State *g = G(L);
662 if(is_block_gc(L)) return;
663 set_block_gc(L);
637 if (g->gcstate <= GCSpropagate) { 664 if (g->gcstate <= GCSpropagate) {
638 /* reset sweep marks to sweep all elements (returning them to white) */ 665 /* reset sweep marks to sweep all elements (returning them to white) */
639 g->sweepstrgc = 0; 666 g->sweepstrgc = 0;
@@ -649,12 +676,15 @@ void luaC_fullgc (lua_State *L) {
649 while (g->gcstate != GCSfinalize) { 676 while (g->gcstate != GCSfinalize) {
650 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); 677 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
651 singlestep(L); 678 singlestep(L);
679 yield();
652 } 680 }
653 markroot(L); 681 markroot(L);
654 while (g->gcstate != GCSpause) { 682 while (g->gcstate != GCSpause) {
655 singlestep(L); 683 singlestep(L);
684 yield();
656 } 685 }
657 setthreshold(g); 686 setthreshold(g);
687 unset_block_gc(L);
658} 688}
659 689
660 690
@@ -682,6 +712,14 @@ void luaC_barrierback (lua_State *L, Table *t) {
682} 712}
683 713
684 714
715void luaC_marknew (lua_State *L, GCObject *o) {
716 global_State *g = G(L);
717 o->gch.marked = luaC_white(g);
718 if (g->gcstate == GCSpropagate)
719 reallymarkobject(g, o); /* mark new objects as gray during propagate state. */
720}
721
722
685void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { 723void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
686 global_State *g = G(L); 724 global_State *g = G(L);
687 o->gch.next = g->rootgc; 725 o->gch.next = g->rootgc;