diff options
Diffstat (limited to 'apps/plugins/lua/lgc.c')
-rw-r--r-- | apps/plugins/lua/lgc.c | 60 |
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 | ||
62 | static void removeentry (Node *n) { | 65 | static 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 | ||
562 | static 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 | ||
556 | static l_mem singlestep (lua_State *L) { | 572 | static 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 | ||
610 | void luaC_step (lua_State *L) { | 621 | void 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 | ||
651 | int 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 | |||
635 | void luaC_fullgc (lua_State *L) { | 660 | void 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 | ||
715 | void 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 | |||
685 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { | 723 | void 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; |