diff options
-rw-r--r-- | lgc.c | 133 | ||||
-rw-r--r-- | lgc.h | 7 | ||||
-rw-r--r-- | lstate.c | 14 | ||||
-rw-r--r-- | lstate.h | 6 |
4 files changed, 50 insertions, 110 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.60 2009/11/06 17:06:19 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.61 2009/11/09 18:29:21 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -52,9 +52,6 @@ | |||
52 | reallymarkobject(g, obj2gco(t)); } | 52 | reallymarkobject(g, obj2gco(t)); } |
53 | 53 | ||
54 | 54 | ||
55 | #define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpause) | ||
56 | |||
57 | |||
58 | static void reallymarkobject (global_State *g, GCObject *o); | 55 | static void reallymarkobject (global_State *g, GCObject *o); |
59 | 56 | ||
60 | 57 | ||
@@ -94,6 +91,7 @@ static int iscleared (const TValue *o, int iskey) { | |||
94 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | 91 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); |
95 | } | 92 | } |
96 | 93 | ||
94 | |||
97 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | 95 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { |
98 | global_State *g = G(L); | 96 | global_State *g = G(L); |
99 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 97 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
@@ -363,7 +361,6 @@ static void traverseproto (global_State *g, Proto *f) { | |||
363 | } | 361 | } |
364 | 362 | ||
365 | 363 | ||
366 | |||
367 | static void traverseclosure (global_State *g, Closure *cl) { | 364 | static void traverseclosure (global_State *g, Closure *cl) { |
368 | markobject(g, cl->c.env); | 365 | markobject(g, cl->c.env); |
369 | if (cl->c.isC) { | 366 | if (cl->c.isC) { |
@@ -443,10 +440,8 @@ static l_mem propagatemark (global_State *g) { | |||
443 | } | 440 | } |
444 | 441 | ||
445 | 442 | ||
446 | static size_t propagateall (global_State *g) { | 443 | static void propagateall (global_State *g) { |
447 | size_t m = 0; | 444 | while (g->gray) propagatemark(g); |
448 | while (g->gray) m += propagatemark(g); | ||
449 | return m; | ||
450 | } | 445 | } |
451 | 446 | ||
452 | 447 | ||
@@ -615,6 +610,8 @@ static void GCTM (lua_State *L, int propagateerrors) { | |||
615 | setuvalue(L, L->top+1, udata); | 610 | setuvalue(L, L->top+1, udata); |
616 | L->top += 2; | 611 | L->top += 2; |
617 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | 612 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
613 | L->allowhook = oldah; /* restore hooks */ | ||
614 | g->GCthreshold = oldt; /* restore threshold */ | ||
618 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | 615 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
619 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ | 616 | if (status == LUA_ERRRUN) { /* is there an error msg.? */ |
620 | luaO_pushfstring(L, "error in __gc tag method (%s)", | 617 | luaO_pushfstring(L, "error in __gc tag method (%s)", |
@@ -623,24 +620,13 @@ static void GCTM (lua_State *L, int propagateerrors) { | |||
623 | } | 620 | } |
624 | luaD_throw(L, status); /* re-send error */ | 621 | luaD_throw(L, status); /* re-send error */ |
625 | } | 622 | } |
626 | L->allowhook = oldah; /* restore hooks */ | ||
627 | g->GCthreshold = oldt; /* restore threshold */ | ||
628 | } | 623 | } |
629 | } | 624 | } |
630 | 625 | ||
631 | 626 | ||
632 | /* | ||
633 | ** Call all GC tag methods (without raising errors) | ||
634 | */ | ||
635 | void luaC_callAllGCTM (lua_State *L) { | ||
636 | while (G(L)->tobefnz) GCTM(L, 0); | ||
637 | } | ||
638 | |||
639 | |||
640 | /* move 'dead' udata that need finalization to list 'tobefnz' */ | 627 | /* move 'dead' udata that need finalization to list 'tobefnz' */ |
641 | size_t luaC_separateudata (lua_State *L, int all) { | 628 | void luaC_separateudata (lua_State *L, int all) { |
642 | global_State *g = G(L); | 629 | global_State *g = G(L); |
643 | size_t deadmem = 0; /* total size of all objects to be finalized */ | ||
644 | GCObject **p = &g->mainthread->next; | 630 | GCObject **p = &g->mainthread->next; |
645 | GCObject *curr; | 631 | GCObject *curr; |
646 | GCObject **lastnext = &g->tobefnz; | 632 | GCObject **lastnext = &g->tobefnz; |
@@ -653,7 +639,6 @@ size_t luaC_separateudata (lua_State *L, int all) { | |||
653 | p = &gch(curr)->next; /* don't bother with it */ | 639 | p = &gch(curr)->next; /* don't bother with it */ |
654 | else { | 640 | else { |
655 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 641 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
656 | deadmem += sizeudata(gco2u(curr)); | ||
657 | *p = gch(curr)->next; /* remove 'curr' from 'rootgc' list */ | 642 | *p = gch(curr)->next; /* remove 'curr' from 'rootgc' list */ |
658 | /* link 'curr' at the end of 'tobefnz' list */ | 643 | /* link 'curr' at the end of 'tobefnz' list */ |
659 | gch(curr)->next = *lastnext; | 644 | gch(curr)->next = *lastnext; |
@@ -661,7 +646,6 @@ size_t luaC_separateudata (lua_State *L, int all) { | |||
661 | lastnext = &gch(curr)->next; | 646 | lastnext = &gch(curr)->next; |
662 | } | 647 | } |
663 | } | 648 | } |
664 | return deadmem; | ||
665 | } | 649 | } |
666 | 650 | ||
667 | 651 | ||
@@ -691,15 +675,15 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) { | |||
691 | ** ======================================================= | 675 | ** ======================================================= |
692 | */ | 676 | */ |
693 | 677 | ||
694 | void luaC_freeall (lua_State *L) { | 678 | void luaC_freeallobjects (lua_State *L) { |
695 | global_State *g = G(L); | 679 | global_State *g = G(L); |
696 | int i; | 680 | int i; |
697 | lua_assert(g->tobefnz == NULL); | 681 | while (g->tobefnz) GCTM(L, 0); /* Call all pending finalizers */ |
698 | /* mask to collect all elements */ | 682 | /* following "white" makes all objects look dead */ |
699 | g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); | 683 | g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); |
700 | sweepwholelist(L, &g->rootgc); | 684 | sweepwholelist(L, &g->rootgc); |
701 | lua_assert(g->rootgc == obj2gco(g->mainthread)); | 685 | lua_assert(g->rootgc == obj2gco(g->mainthread) && |
702 | lua_assert(g->mainthread->next == NULL); | 686 | g->mainthread->next == NULL); |
703 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ | 687 | for (i = 0; i < g->strt.size; i++) /* free all string lists */ |
704 | sweepwholelist(L, &g->strt.hash[i]); | 688 | sweepwholelist(L, &g->strt.hash[i]); |
705 | lua_assert(g->strt.nuse == 0); | 689 | lua_assert(g->strt.nuse == 0); |
@@ -708,49 +692,37 @@ void luaC_freeall (lua_State *L) { | |||
708 | 692 | ||
709 | static void atomic (lua_State *L) { | 693 | static void atomic (lua_State *L) { |
710 | global_State *g = G(L); | 694 | global_State *g = G(L); |
711 | size_t udsize; /* total size of userdata to be finalized */ | 695 | g->gcstate = GCSatomic; |
712 | /* global table and registry may be changed by API */ | 696 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
697 | markobject(g, L); /* mark running thread */ | ||
698 | /* global table, registry, and global metatables may be changed by API */ | ||
713 | markvalue(g, &g->l_gt); | 699 | markvalue(g, &g->l_gt); |
714 | markvalue(g, &g->l_registry); | 700 | markvalue(g, &g->l_registry); |
701 | markmt(g); /* mark basic metatables */ | ||
715 | /* remark occasional upvalues of (maybe) dead threads */ | 702 | /* remark occasional upvalues of (maybe) dead threads */ |
716 | g->gcstate = GCSatomic; | ||
717 | remarkupvals(g); | 703 | remarkupvals(g); |
718 | /* traverse objects caught by write barrier and by 'remarkupvals' */ | 704 | /* traverse objects caught by write barrier and by 'remarkupvals' */ |
719 | propagateall(g); | 705 | propagateall(g); |
720 | /* remark weak tables */ | 706 | /* at this point, all strongly accessible objects are marked. |
721 | g->gray = g->weak; | 707 | Start marking weakily accessible objects. */ |
722 | g->weak = NULL; | 708 | traverselistofgrays(g, &g->weak); /* remark weak tables */ |
723 | lua_assert(!iswhite(obj2gco(g->mainthread))); | ||
724 | markobject(g, L); /* mark running thread */ | ||
725 | markmt(g); /* mark basic metatables (again) */ | ||
726 | propagateall(g); | ||
727 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ | 709 | traverselistofgrays(g, &g->ephemeron); /* remark ephemeron tables */ |
728 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ | 710 | traverselistofgrays(g, &g->grayagain); /* remark gray again */ |
729 | convergeephemerons(g); | 711 | convergeephemerons(g); |
730 | udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ | 712 | luaC_separateudata(L, 0); /* separate userdata to be finalized */ |
731 | markbeingfnz(g); /* mark userdata that will be finalized */ | 713 | markbeingfnz(g); /* mark userdata that will be finalized */ |
732 | udsize += propagateall(g); /* remark, to propagate `preserveness' */ | 714 | propagateall(g); /* remark, to propagate `preserveness' */ |
733 | convergeephemerons(g); | 715 | convergeephemerons(g); |
734 | /* remove collected objects from weak tables */ | 716 | /* remove collected objects from weak tables */ |
735 | cleartable(g->weak); | 717 | cleartable(g->weak); |
736 | cleartable(g->ephemeron); | 718 | cleartable(g->ephemeron); |
737 | cleartable(g->allweak); | 719 | cleartable(g->allweak); |
738 | /* flip current white */ | 720 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ |
739 | g->currentwhite = cast_byte(otherwhite(g)); | 721 | g->sweepstrgc = 0; /* go to sweep phase */ |
740 | g->sweepstrgc = 0; | ||
741 | g->gcstate = GCSsweepstring; | 722 | g->gcstate = GCSsweepstring; |
742 | lua_assert(g->totalbytes > udsize); | ||
743 | g->estimate = g->totalbytes - udsize; /* first estimate */ | ||
744 | } | 723 | } |
745 | 724 | ||
746 | 725 | ||
747 | #define correctestimate(g,s) { \ | ||
748 | lu_mem old = g->totalbytes; s; \ | ||
749 | lua_assert(old >= g->totalbytes); \ | ||
750 | if (g->estimate >= old - g->totalbytes) \ | ||
751 | g->estimate -= (old - g->totalbytes);} | ||
752 | |||
753 | |||
754 | static l_mem singlestep (lua_State *L) { | 726 | static l_mem singlestep (lua_State *L) { |
755 | global_State *g = G(L); | 727 | global_State *g = G(L); |
756 | /*lua_checkmemory(L);*/ | 728 | /*lua_checkmemory(L);*/ |
@@ -768,7 +740,7 @@ static l_mem singlestep (lua_State *L) { | |||
768 | } | 740 | } |
769 | } | 741 | } |
770 | case GCSsweepstring: { | 742 | case GCSsweepstring: { |
771 | correctestimate(g, sweepwholelist(L, &g->strt.hash[g->sweepstrgc++])); | 743 | sweepwholelist(L, &g->strt.hash[g->sweepstrgc++]); |
772 | if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */ | 744 | if (g->sweepstrgc >= g->strt.size) { /* nothing more to sweep? */ |
773 | g->sweepgc = &g->rootgc; | 745 | g->sweepgc = &g->rootgc; |
774 | g->gcstate = GCSsweep; /* sweep all other objects */ | 746 | g->gcstate = GCSsweep; /* sweep all other objects */ |
@@ -776,7 +748,7 @@ static l_mem singlestep (lua_State *L) { | |||
776 | return GCSWEEPCOST; | 748 | return GCSWEEPCOST; |
777 | } | 749 | } |
778 | case GCSsweep: { | 750 | case GCSsweep: { |
779 | correctestimate(g, g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX)); | 751 | g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); |
780 | if (*g->sweepgc == NULL) /* nothing more to sweep? */ | 752 | if (*g->sweepgc == NULL) /* nothing more to sweep? */ |
781 | g->gcstate = GCSfinalize; /* end sweep phase */ | 753 | g->gcstate = GCSfinalize; /* end sweep phase */ |
782 | return GCSWEEPMAX*GCSWEEPCOST; | 754 | return GCSWEEPMAX*GCSWEEPCOST; |
@@ -784,14 +756,11 @@ static l_mem singlestep (lua_State *L) { | |||
784 | case GCSfinalize: { | 756 | case GCSfinalize: { |
785 | if (g->tobefnz) { | 757 | if (g->tobefnz) { |
786 | GCTM(L, 1); | 758 | GCTM(L, 1); |
787 | if (g->estimate > GCFINALIZECOST) | ||
788 | g->estimate -= GCFINALIZECOST; | ||
789 | return GCFINALIZECOST; | 759 | return GCFINALIZECOST; |
790 | } | 760 | } |
791 | else { | 761 | else { |
792 | correctestimate(g, checkSizes(L)); | 762 | checkSizes(L); |
793 | g->gcstate = GCSpause; /* end collection */ | 763 | g->gcstate = GCSpause; /* end collection */ |
794 | g->gcdept = 0; | ||
795 | return 0; | 764 | return 0; |
796 | } | 765 | } |
797 | } | 766 | } |
@@ -802,29 +771,17 @@ static l_mem singlestep (lua_State *L) { | |||
802 | 771 | ||
803 | void luaC_step (lua_State *L) { | 772 | void luaC_step (lua_State *L) { |
804 | global_State *g = G(L); | 773 | global_State *g = G(L); |
805 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; | 774 | l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; /* how much to work */ |
775 | lu_mem debt = g->totalbytes - g->GCthreshold; | ||
806 | lua_assert(g->gckind == KGC_NORMAL); | 776 | lua_assert(g->gckind == KGC_NORMAL); |
807 | if (lim == 0) | 777 | do { /* always perform at least one single step */ |
808 | lim = (MAX_LUMEM-1)/2; /* no limit */ | ||
809 | g->gcdept += g->totalbytes - g->GCthreshold; | ||
810 | do { | ||
811 | lim -= singlestep(L); | 778 | lim -= singlestep(L); |
812 | if (g->gcstate == GCSpause) | 779 | } while (lim > 0 && g->gcstate != GCSpause); |
813 | break; | 780 | g->GCthreshold = (g->gcstate != GCSpause) |
814 | } while (lim > 0); | 781 | ? g->totalbytes + GCSTEPSIZE |
815 | if (g->gcstate != GCSpause) { | 782 | : (g->totalbytes/100) * g->gcpause; |
816 | if (g->gcdept < GCSTEPSIZE) | 783 | /* compensate if GC is "behind schedule" (has some debt to pay) */ |
817 | g->GCthreshold = g->totalbytes + GCSTEPSIZE; /* - lim/g->gcstepmul;*/ | 784 | if (g->GCthreshold > debt) g->GCthreshold -= debt; |
818 | else { | ||
819 | g->gcdept -= GCSTEPSIZE; | ||
820 | g->GCthreshold = g->totalbytes; | ||
821 | } | ||
822 | } | ||
823 | else { | ||
824 | if (g->estimate > g->totalbytes) | ||
825 | g->estimate = g->totalbytes; | ||
826 | setthreshold(g); | ||
827 | } | ||
828 | } | 785 | } |
829 | 786 | ||
830 | 787 | ||
@@ -832,21 +789,15 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
832 | global_State *g = G(L); | 789 | global_State *g = G(L); |
833 | lua_assert(g->gckind == KGC_NORMAL); | 790 | lua_assert(g->gckind == KGC_NORMAL); |
834 | g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; | 791 | g->gckind = isemergency ? KGC_EMERGENCY : KGC_FORCED; |
835 | if (g->gcstate <= GCSpropagate) { | 792 | if (g->gcstate == GCSpropagate) { /* marking phase? */ |
836 | /* reset other collector lists */ | 793 | /* must sweep all objects to turn them back to white |
837 | g->gray = NULL; | 794 | (as white does not change, nothing will be collected) */ |
838 | g->grayagain = NULL; | ||
839 | g->weak = g->ephemeron = g->allweak = NULL; | ||
840 | g->sweepstrgc = 0; | 795 | g->sweepstrgc = 0; |
841 | g->gcstate = GCSsweepstring; | 796 | g->gcstate = GCSsweepstring; |
842 | } | 797 | } |
843 | lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate); | ||
844 | /* finish any pending sweep phase */ | 798 | /* finish any pending sweep phase */ |
845 | while (g->gcstate != GCSfinalize) { | 799 | while (issweep(g)) singlestep(L); |
846 | lua_assert(issweep(g)); | 800 | markroot(L); /* start a new collection */ |
847 | singlestep(L); | ||
848 | } | ||
849 | markroot(L); | ||
850 | /* run collector up to finalizers */ | 801 | /* run collector up to finalizers */ |
851 | while (g->gcstate != GCSfinalize) | 802 | while (g->gcstate != GCSfinalize) |
852 | singlestep(L); | 803 | singlestep(L); |
@@ -855,7 +806,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
855 | while (g->gcstate != GCSpause) | 806 | while (g->gcstate != GCSpause) |
856 | singlestep(L); | 807 | singlestep(L); |
857 | } | 808 | } |
858 | setthreshold(g); | 809 | g->GCthreshold = (g->totalbytes/100) * g->gcpause; |
859 | } | 810 | } |
860 | 811 | ||
861 | /* }====================================================== */ | 812 | /* }====================================================== */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.21 2009/06/08 19:35:59 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.22 2009/11/17 11:56:03 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -95,9 +95,8 @@ | |||
95 | #define luaC_objbarriert(L,t,o) \ | 95 | #define luaC_objbarriert(L,t,o) \ |
96 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } | 96 | { if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); } |
97 | 97 | ||
98 | LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); | 98 | LUAI_FUNC void luaC_separateudata (lua_State *L, int all); |
99 | LUAI_FUNC void luaC_callAllGCTM (lua_State *L); | 99 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
100 | LUAI_FUNC void luaC_freeall (lua_State *L); | ||
101 | LUAI_FUNC void luaC_step (lua_State *L); | 100 | LUAI_FUNC void luaC_step (lua_State *L); |
102 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); | 101 | LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); |
103 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | 102 | LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.62 2009/10/05 16:44:33 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.63 2009/10/23 19:12:19 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -139,7 +139,6 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
139 | luaT_init(L); | 139 | luaT_init(L); |
140 | luaX_init(L); | 140 | luaX_init(L); |
141 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); | 141 | luaS_fix(luaS_newliteral(L, MEMERRMSG)); |
142 | g->estimate = g->totalbytes; | ||
143 | g->GCthreshold = 4*g->totalbytes; | 142 | g->GCthreshold = 4*g->totalbytes; |
144 | } | 143 | } |
145 | 144 | ||
@@ -170,7 +169,7 @@ static void preinit_state (lua_State *L, global_State *g) { | |||
170 | static void close_state (lua_State *L) { | 169 | static void close_state (lua_State *L) { |
171 | global_State *g = G(L); | 170 | global_State *g = G(L); |
172 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | 171 | luaF_close(L, L->stack); /* close all upvalues for this thread */ |
173 | luaC_freeall(L); /* collect all objects */ | 172 | luaC_freeallobjects(L); /* collect all objects */ |
174 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); | 173 | luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); |
175 | luaZ_freebuffer(L, &g->buff); | 174 | luaZ_freebuffer(L, &g->buff); |
176 | freestack(L); | 175 | freestack(L); |
@@ -241,16 +240,10 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
241 | g->version = lua_version(NULL); | 240 | g->version = lua_version(NULL); |
242 | g->gcstate = GCSpause; | 241 | g->gcstate = GCSpause; |
243 | g->rootgc = obj2gco(L); | 242 | g->rootgc = obj2gco(L); |
244 | g->sweepstrgc = 0; | ||
245 | g->sweepgc = &g->rootgc; | ||
246 | g->gray = NULL; | ||
247 | g->grayagain = NULL; | ||
248 | g->weak = g->ephemeron = g->allweak = NULL; | ||
249 | g->tobefnz = NULL; | 243 | g->tobefnz = NULL; |
250 | g->estimate = g->totalbytes = sizeof(LG); | 244 | g->totalbytes = sizeof(LG); |
251 | g->gcpause = LUAI_GCPAUSE; | 245 | g->gcpause = LUAI_GCPAUSE; |
252 | g->gcstepmul = LUAI_GCMUL; | 246 | g->gcstepmul = LUAI_GCMUL; |
253 | g->gcdept = 0; | ||
254 | for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; | 247 | for (i=0; i<NUM_TAGS; i++) g->mt[i] = NULL; |
255 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { | 248 | if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { |
256 | /* memory allocation error: free partial state */ | 249 | /* memory allocation error: free partial state */ |
@@ -269,7 +262,6 @@ LUA_API void lua_close (lua_State *L) { | |||
269 | luaF_close(L, L->stack); /* close all upvalues for this thread */ | 262 | luaF_close(L, L->stack); /* close all upvalues for this thread */ |
270 | luaC_separateudata(L, 1); /* separate all udata with GC metamethods */ | 263 | luaC_separateudata(L, 1); /* separate all udata with GC metamethods */ |
271 | lua_assert(L->next == NULL); | 264 | lua_assert(L->next == NULL); |
272 | luaC_callAllGCTM(L); /* call GC metamethods for all udata */ | ||
273 | luai_userstateclose(L); | 265 | luai_userstateclose(L); |
274 | close_state(L); | 266 | close_state(L); |
275 | } | 267 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.46 2009/07/15 17:26:14 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.47 2009/10/23 19:12:19 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -132,10 +132,8 @@ typedef struct global_State { | |||
132 | GCObject *allweak; /* list of all-weak tables */ | 132 | GCObject *allweak; /* list of all-weak tables */ |
133 | GCObject *tobefnz; /* list of userdata to be GC */ | 133 | GCObject *tobefnz; /* list of userdata to be GC */ |
134 | Mbuffer buff; /* temporary buffer for string concatentation */ | 134 | Mbuffer buff; /* temporary buffer for string concatentation */ |
135 | lu_mem GCthreshold; | 135 | lu_mem GCthreshold; /* when totalbytes > GCthreshold, run GC step */ |
136 | lu_mem totalbytes; /* number of bytes currently allocated */ | 136 | lu_mem totalbytes; /* number of bytes currently allocated */ |
137 | lu_mem estimate; /* an estimate of number of bytes actually in use */ | ||
138 | lu_mem gcdept; /* how much GC is `behind schedule' */ | ||
139 | int gcpause; /* size of pause between successive GCs */ | 137 | int gcpause; /* size of pause between successive GCs */ |
140 | int gcstepmul; /* GC `granularity' */ | 138 | int gcstepmul; /* GC `granularity' */ |
141 | lua_CFunction panic; /* to be called in unprotected errors */ | 139 | lua_CFunction panic; /* to be called in unprotected errors */ |