summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c133
-rw-r--r--lgc.h7
-rw-r--r--lstate.c14
-rw-r--r--lstate.h6
4 files changed, 50 insertions, 110 deletions
diff --git a/lgc.c b/lgc.c
index 91ed52dd..b706f37c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
58static void reallymarkobject (global_State *g, GCObject *o); 55static 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
97void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { 95void 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
367static void traverseclosure (global_State *g, Closure *cl) { 364static 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
446static size_t propagateall (global_State *g) { 443static 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*/
635void 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' */
641size_t luaC_separateudata (lua_State *L, int all) { 628void 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
694void luaC_freeall (lua_State *L) { 678void 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
709static void atomic (lua_State *L) { 693static 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
754static l_mem singlestep (lua_State *L) { 726static 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
803void luaC_step (lua_State *L) { 772void 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/* }====================================================== */
diff --git a/lgc.h b/lgc.h
index e79eb5db..8a671322 100644
--- a/lgc.h
+++ b/lgc.h
@@ -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
98LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all); 98LUAI_FUNC void luaC_separateudata (lua_State *L, int all);
99LUAI_FUNC void luaC_callAllGCTM (lua_State *L); 99LUAI_FUNC void luaC_freeallobjects (lua_State *L);
100LUAI_FUNC void luaC_freeall (lua_State *L);
101LUAI_FUNC void luaC_step (lua_State *L); 100LUAI_FUNC void luaC_step (lua_State *L);
102LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); 101LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
103LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt); 102LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
diff --git a/lstate.c b/lstate.c
index cb52eac3..f02c17ed 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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) {
170static void close_state (lua_State *L) { 169static 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}
diff --git a/lstate.h b/lstate.h
index dcceefe1..84847eae 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */