aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-09-30 14:01:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-09-30 14:01:42 -0300
commit3d54b42d59bcc1b31a369f3497ac22745d63cae6 (patch)
tree283f8d935865e1cb6d01e25f3d745f91229d22c8
parente4f418f07c7349f5ff844fbdc9a3b37b488113a5 (diff)
downloadlua-3d54b42d59bcc1b31a369f3497ac22745d63cae6.tar.gz
lua-3d54b42d59bcc1b31a369f3497ac22745d63cae6.tar.bz2
lua-3d54b42d59bcc1b31a369f3497ac22745d63cae6.zip
'objsize' broke in smaller pieces
-rw-r--r--lfunc.c15
-rw-r--r--lfunc.h1
-rw-r--r--lgc.c58
-rw-r--r--lgc.h15
-rw-r--r--lstate.c8
-rw-r--r--lstate.h1
-rw-r--r--ltable.c12
-rw-r--r--ltable.h1
-rw-r--r--manual/manual.of43
9 files changed, 91 insertions, 63 deletions
diff --git a/lfunc.c b/lfunc.c
index d650c000..2b041281 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -264,6 +264,21 @@ Proto *luaF_newproto (lua_State *L) {
264} 264}
265 265
266 266
267size_t luaF_protosize (Proto *p) {
268 size_t sz = sizeof(Proto)
269 + cast_uint(p->sizep) * sizeof(Proto*)
270 + cast_uint(p->sizek) * sizeof(TValue)
271 + cast_uint(p->sizelocvars) * sizeof(LocVar)
272 + cast_uint(p->sizeupvalues) * sizeof(Upvaldesc);
273 if (!(p->flag & PF_FIXED)) {
274 sz += cast_uint(p->sizecode) * sizeof(Instruction)
275 + cast_uint(p->sizelineinfo) * sizeof(lu_byte)
276 + cast_uint(p->sizeabslineinfo) * sizeof(AbsLineInfo);
277 }
278 return sz;
279}
280
281
267void luaF_freeproto (lua_State *L, Proto *f) { 282void luaF_freeproto (lua_State *L, Proto *f) {
268 if (!(f->flag & PF_FIXED)) { 283 if (!(f->flag & PF_FIXED)) {
269 luaM_freearray(L, f->code, cast_sizet(f->sizecode)); 284 luaM_freearray(L, f->code, cast_sizet(f->sizecode));
diff --git a/lfunc.h b/lfunc.h
index 162b55ec..b9651074 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -56,6 +56,7 @@ LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
56LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); 56LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
57LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy); 57LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy);
58LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 58LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
59LUAI_FUNC size_t luaF_protosize (Proto *p);
59LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); 60LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
60LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, 61LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
61 int pc); 62 int pc);
diff --git a/lgc.c b/lgc.c
index a38d11b2..e154402b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -113,13 +113,7 @@ static void entersweep (lua_State *L);
113static size_t objsize (GCObject *o) { 113static size_t objsize (GCObject *o) {
114 switch (o->tt) { 114 switch (o->tt) {
115 case LUA_VTABLE: { 115 case LUA_VTABLE: {
116 /* Fow now, table size does not consider 'haslastfree' */ 116 return luaH_size(gco2t(o));
117 Table *t = gco2t(o);
118 size_t sz = sizeof(Table)
119 + luaH_realasize(t) * (sizeof(Value) + 1);
120 if (!isdummy(t))
121 sz += sizenode(t) * sizeof(Node);
122 return sz;
123 } 117 }
124 case LUA_VLCL: { 118 case LUA_VLCL: {
125 LClosure *cl = gco2lcl(o); 119 LClosure *cl = gco2lcl(o);
@@ -135,26 +129,10 @@ static size_t objsize (GCObject *o) {
135 return sizeudata(u->nuvalue, u->len); 129 return sizeudata(u->nuvalue, u->len);
136 } 130 }
137 case LUA_VPROTO: { 131 case LUA_VPROTO: {
138 Proto *p = gco2p(o); 132 return luaF_protosize(gco2p(o));
139 size_t sz = sizeof(Proto)
140 + cast_uint(p->sizep) * sizeof(Proto*)
141 + cast_uint(p->sizek) * sizeof(TValue)
142 + cast_uint(p->sizelocvars) * sizeof(LocVar)
143 + cast_uint(p->sizeupvalues) * sizeof(Upvaldesc);
144 if (!(p->flag & PF_FIXED)) {
145 sz += cast_uint(p->sizecode) * sizeof(Instruction)
146 + cast_uint(p->sizelineinfo) * sizeof(lu_byte)
147 + cast_uint(p->sizeabslineinfo) * sizeof(AbsLineInfo);
148 }
149 return sz;
150 } 133 }
151 case LUA_VTHREAD: { 134 case LUA_VTHREAD: {
152 lua_State *L1 = gco2th(o); 135 return luaE_statesize(gco2th(o));
153 size_t sz = sizeof(lua_State) + LUA_EXTRASPACE
154 + cast_uint(L1->nci) * sizeof(CallInfo);
155 if (L1->stack.p != NULL)
156 sz += cast_uint(stacksize(L1) + EXTRA_STACK) * sizeof(StackValue);
157 return sz;
158 } 136 }
159 case LUA_VSHRSTR: { 137 case LUA_VSHRSTR: {
160 TString *ts = gco2ts(o); 138 TString *ts = gco2ts(o);
@@ -164,7 +142,9 @@ static size_t objsize (GCObject *o) {
164 TString *ts = gco2ts(o); 142 TString *ts = gco2ts(o);
165 return luaS_sizelngstr(ts->u.lnglen, ts->shrlen); 143 return luaS_sizelngstr(ts->u.lnglen, ts->shrlen);
166 } 144 }
167 case LUA_VUPVAL: return sizeof(UpVal); 145 case LUA_VUPVAL: {
146 return sizeof(UpVal);
147 }
168 default: lua_assert(0); return 0; 148 default: lua_assert(0); return 0;
169 } 149 }
170} 150}
@@ -615,7 +595,7 @@ static l_mem traversetable (global_State *g, Table *h) {
615 } 595 }
616 else /* not weak */ 596 else /* not weak */
617 traversestrongtable(g, h); 597 traversestrongtable(g, h);
618 return 1 + sizenode(h) + h->alimit; 598 return 1 + 2*sizenode(h) + h->alimit;
619} 599}
620 600
621 601
@@ -1291,10 +1271,11 @@ static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
1291/* 1271/*
1292** Decide whether to shift to major mode. It tests two conditions: 1272** Decide whether to shift to major mode. It tests two conditions:
1293** 1) Whether the number of added old objects in this collection is more 1273** 1) Whether the number of added old objects in this collection is more
1294** than half the number of new objects. ('step' is the number of objects 1274** than half the number of new objects. ('step' is equal to the debt set
1295** created between minor collections. Except for forward barriers, it 1275** to trigger the next minor collection; that is equal to the number
1296** is the maximum number of objects that can become old in each minor 1276** of objects created since the previous minor collection. Except for
1297** collection.) 1277** forward barriers, it is the maximum number of objects that can become
1278** old in each minor collection.)
1298** 2) Whether the accumulated number of added old objects is larger 1279** 2) Whether the accumulated number of added old objects is larger
1299** than 'minormajor'% of the number of lived objects after the last 1280** than 'minormajor'% of the number of lived objects after the last
1300** major collection. (That percentage is computed in 'limit'.) 1281** major collection. (That percentage is computed in 'limit'.)
@@ -1678,7 +1659,7 @@ void luaC_runtilstate (lua_State *L, int state, int fast) {
1678 1659
1679 1660
1680/* 1661/*
1681** Performs a basic incremental step. The debt and step size are 1662** Performs a basic incremental step. The step size is
1682** converted from bytes to "units of work"; then the function loops 1663** converted from bytes to "units of work"; then the function loops
1683** running single steps until adding that many units of work or 1664** running single steps until adding that many units of work or
1684** finishing a cycle (pause state). Finally, it sets the debt that 1665** finishing a cycle (pause state). Finally, it sets the debt that
@@ -1689,7 +1670,9 @@ static void incstep (lua_State *L, global_State *g) {
1689 l_mem work2do = applygcparam(g, STEPMUL, stepsize); 1670 l_mem work2do = applygcparam(g, STEPMUL, stepsize);
1690 l_mem stres; 1671 l_mem stres;
1691 int fast = (work2do == 0); /* special case: do a full collection */ 1672 int fast = (work2do == 0); /* special case: do a full collection */
1673//printf("\n** %ld %ld %d\n", work2do, stepsize, g->gcstate);
1692 do { /* repeat until enough work */ 1674 do { /* repeat until enough work */
1675//printf("%d-", g->gcstate);
1693 stres = singlestep(L, fast); /* perform one single step */ 1676 stres = singlestep(L, fast); /* perform one single step */
1694 if (stres == step2minor) /* returned to minor collections? */ 1677 if (stres == step2minor) /* returned to minor collections? */
1695 return; /* nothing else to be done here */ 1678 return; /* nothing else to be done here */
@@ -1716,21 +1699,20 @@ void luaC_step (lua_State *L) {
1716 if (!gcrunning(g)) /* not running? */ 1699 if (!gcrunning(g)) /* not running? */
1717 luaE_setdebt(g, 20000); 1700 luaE_setdebt(g, 20000);
1718 else { 1701 else {
1719// printf("mem: %ld kind: %s ", gettotalbytes(g), 1702//printf("mem: %ld kind: %s ", gettotalbytes(g),
1720// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" : 1703// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
1721// "genminor"); 1704// "genminor");
1722 switch (g->gckind) { 1705 switch (g->gckind) {
1723 case KGC_INC: case KGC_GENMAJOR: 1706 case KGC_INC: case KGC_GENMAJOR:
1724// printf("(%d -> ", g->gcstate);
1725 incstep(L, g); 1707 incstep(L, g);
1726// printf("%d) ", g->gcstate); 1708//printf("%d) ", g->gcstate);
1727 break; 1709 break;
1728 case KGC_GENMINOR: 1710 case KGC_GENMINOR:
1729 youngcollection(L, g); 1711 youngcollection(L, g);
1730 setminordebt(g); 1712 setminordebt(g);
1731 break; 1713 break;
1732 } 1714 }
1733// printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt); 1715//printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
1734 } 1716 }
1735} 1717}
1736 1718
diff --git a/lgc.h b/lgc.h
index 0b16ac7f..a3bc746a 100644
--- a/lgc.h
+++ b/lgc.h
@@ -160,7 +160,11 @@
160*/ 160*/
161 161
162 162
163/* Default Values for GC parameters */ 163/*
164** {======================================================
165** Default Values for GC parameters
166** =======================================================
167*/
164 168
165/* 169/*
166** Minor collections will shift to major ones after LUAI_MINORMAJOR% 170** Minor collections will shift to major ones after LUAI_MINORMAJOR%
@@ -189,17 +193,20 @@
189/* 193/*
190** Step multiplier: The collector handles LUAI_GCMUL% work units for 194** Step multiplier: The collector handles LUAI_GCMUL% work units for
191** each new allocated byte. (Each "work unit" corresponds roughly to 195** each new allocated byte. (Each "work unit" corresponds roughly to
192** sweeping or marking one object.) 196** sweeping one object or traversing one slot.)
193*/ 197*/
194#define LUAI_GCMUL 20 /* ??? */ 198#define LUAI_GCMUL 40
195 199
196/* How many bytes to allocate before next GC step */ 200/* How many bytes to allocate before next GC step */
197#define LUAI_GCSTEPSIZE (250 * sizeof(void*)) 201#define LUAI_GCSTEPSIZE (200 * sizeof(Table))
198 202
199 203
200#define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v)) 204#define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v))
201#define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x) 205#define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x)
202 206
207/* }====================================================== */
208
209
203/* 210/*
204** Control when GC is running: 211** Control when GC is running:
205*/ 212*/
diff --git a/lstate.c b/lstate.c
index 8e7c8b86..d6b9c90f 100644
--- a/lstate.c
+++ b/lstate.c
@@ -257,6 +257,14 @@ static void preinit_thread (lua_State *L, global_State *g) {
257} 257}
258 258
259 259
260size_t luaE_statesize (lua_State *L) {
261 size_t sz = sizeof(LG) + cast_uint(L->nci) * sizeof(CallInfo);
262 if (L->stack.p != NULL)
263 sz += cast_uint(stacksize(L) + EXTRA_STACK) * sizeof(StackValue);
264 return sz;
265}
266
267
260static void close_state (lua_State *L) { 268static void close_state (lua_State *L) {
261 global_State *g = G(L); 269 global_State *g = G(L);
262 if (!completestate(g)) /* closing a partially built state? */ 270 if (!completestate(g)) /* closing a partially built state? */
diff --git a/lstate.h b/lstate.h
index 2a03576d..e2108668 100644
--- a/lstate.h
+++ b/lstate.h
@@ -416,6 +416,7 @@ union GCUnion {
416 416
417LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); 417LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
418LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 418LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
419LUAI_FUNC size_t luaE_statesize (lua_State *L);
419LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); 420LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
420LUAI_FUNC void luaE_shrinkCI (lua_State *L); 421LUAI_FUNC void luaE_shrinkCI (lua_State *L);
421LUAI_FUNC void luaE_checkcstack (lua_State *L); 422LUAI_FUNC void luaE_checkcstack (lua_State *L);
diff --git a/ltable.c b/ltable.c
index 80a1bf84..bf44e82e 100644
--- a/ltable.c
+++ b/ltable.c
@@ -805,6 +805,18 @@ Table *luaH_new (lua_State *L) {
805} 805}
806 806
807 807
808size_t luaH_size (Table *t) {
809 size_t sz = sizeof(Table)
810 + luaH_realasize(t) * (sizeof(Value) + 1);
811 if (!isdummy(t)) {
812 sz += sizenode(t) * sizeof(Node);
813 if (haslastfree(t))
814 sz += sizeof(Limbox);
815 }
816 return sz;
817}
818
819
808/* 820/*
809** Frees a table. 821** Frees a table.
810*/ 822*/
diff --git a/ltable.h b/ltable.h
index c6a87807..c352da38 100644
--- a/ltable.h
+++ b/ltable.h
@@ -163,6 +163,7 @@ LUAI_FUNC Table *luaH_new (lua_State *L);
163LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned nasize, 163LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned nasize,
164 unsigned nhsize); 164 unsigned nhsize);
165LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned nasize); 165LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned nasize);
166LUAI_FUNC size_t luaH_size (Table *t);
166LUAI_FUNC void luaH_free (lua_State *L, Table *t); 167LUAI_FUNC void luaH_free (lua_State *L, Table *t);
167LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); 168LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
168LUAI_FUNC lua_Unsigned luaH_getn (Table *t); 169LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
diff --git a/manual/manual.of b/manual/manual.of
index 1ac537f7..c93fbfcb 100644
--- a/manual/manual.of
+++ b/manual/manual.of
@@ -608,8 +608,8 @@ An object is considered @def{dead}
608as soon as the collector can be sure the object 608as soon as the collector can be sure the object
609will not be accessed again in the normal execution of the program. 609will not be accessed again in the normal execution of the program.
610(@Q{Normal execution} here excludes finalizers, 610(@Q{Normal execution} here excludes finalizers,
611which can resurrect dead objects @see{finalizers}, 611which resurrect dead objects @see{finalizers},
612and excludes also operations using the debug library.) 612and it excludes also some operations using the debug library.)
613Note that the time when the collector can be sure that an object 613Note that the time when the collector can be sure that an object
614is dead may not coincide with the programmer's expectations. 614is dead may not coincide with the programmer's expectations.
615The only guarantees are that Lua will not collect an object 615The only guarantees are that Lua will not collect an object
@@ -657,25 +657,27 @@ and the @def{garbage-collector step size}.
657 657
658The garbage-collector pause 658The garbage-collector pause
659controls how long the collector waits before starting a new cycle. 659controls how long the collector waits before starting a new cycle.
660The collector starts a new cycle when the number of objects 660The collector starts a new cycle when the number of bytes
661hits @M{n%} of the total after the previous collection. 661hits @M{n%} of the total after the previous collection.
662Larger values make the collector less aggressive. 662Larger values make the collector less aggressive.
663Values equal to or less than 100 mean the collector will not wait to 663Values equal to or less than 100 mean the collector will not wait to
664start a new cycle. 664start a new cycle.
665A value of 200 means that the collector waits for 665A value of 200 means that the collector waits for
666the total number of objects to double before starting a new cycle. 666the total number of bytes to double before starting a new cycle.
667 667
668The garbage-collector step size controls the 668The garbage-collector step size controls the
669size of each incremental step, 669size of each incremental step,
670specifically how many objects the interpreter creates 670specifically how many bytes the interpreter allocates
671before performing a step: 671before performing a step:
672A value of @M{n} means the interpreter will create 672A value of @M{n} means the interpreter will allocate
673approximately @M{n} objects between steps. 673approximately @M{n} bytes between steps.
674 674
675The garbage-collector step multiplier 675The garbage-collector step multiplier
676controls the size of each GC step. 676controls how much work each incremental step does.
677A value of @M{n} means the interpreter will mark or sweep, 677A value of @M{n} means the interpreter will execute
678in each step, @M{n%} objects for each created object. 678@M{n%} @emphx{units of work} for each byte allocated.
679A unit of work corresponds roughly to traversing one slot
680or sweeping one object.
679Larger values make the collector more aggressive. 681Larger values make the collector more aggressive.
680Beware that values too small can 682Beware that values too small can
681make the collector too slow to ever finish a cycle. 683make the collector too slow to ever finish a cycle.
@@ -689,7 +691,7 @@ effectively producing a non-incremental, stop-the-world collector.
689In generational mode, 691In generational mode,
690the collector does frequent @emph{minor} collections, 692the collector does frequent @emph{minor} collections,
691which traverses only objects recently created. 693which traverses only objects recently created.
692If after a minor collection the number of objects is above a limit, 694If after a minor collection the number of bytes is above a limit,
693the collector shifts to a @emph{major} collection, 695the collector shifts to a @emph{major} collection,
694which traverses all objects. 696which traverses all objects.
695The collector will then stay doing major collections until 697The collector will then stay doing major collections until
@@ -702,30 +704,30 @@ and the @def{major-minor multiplier}.
702 704
703The minor multiplier controls the frequency of minor collections. 705The minor multiplier controls the frequency of minor collections.
704For a minor multiplier @M{x}, 706For a minor multiplier @M{x},
705a new minor collection will be done when the number of objects 707a new minor collection will be done when the number of bytes
706grows @M{x%} larger than the number in use just 708grows @M{x%} larger than the number in use just
707after the last major collection. 709after the last major collection.
708For instance, for a multiplier of 20, 710For instance, for a multiplier of 20,
709the collector will do a minor collection when the number of objects 711the collector will do a minor collection when the number of bytes
710gets 20% larger than the total after the last major collection. 712gets 20% larger than the total after the last major collection.
711 713
712The minor-major multiplier controls the shift to major collections. 714The minor-major multiplier controls the shift to major collections.
713For a multiplier @M{x}, 715For a multiplier @M{x},
714the collector will shift to a major collection 716the collector will shift to a major collection
715when the number of old objects grows @M{x%} larger 717when the number of bytes from old objects grows @M{x%} larger
716than the total after the previous major collection. 718than the total after the previous major collection.
717For instance, for a multiplier of 100, 719For instance, for a multiplier of 100,
718the collector will do a major collection when the number of old objects 720the collector will do a major collection when the number of old bytes
719gets larger than twice the total after the previous major collection. 721gets larger than twice the total after the previous major collection.
720 722
721The major-minor multiplier controls the shift back to minor collections. 723The major-minor multiplier controls the shift back to minor collections.
722For a multiplier @M{x}, 724For a multiplier @M{x},
723the collector will shift back to minor collections 725the collector will shift back to minor collections
724after a major collection collects at least @M{x%} 726after a major collection collects at least @M{x%}
725of the objects allocated during the last cycle. 727of the bytes allocated during the last cycle.
726In particular, for a multiplier of 0, 728In particular, for a multiplier of 0,
727the collector will immediately shift back to minor collections 729the collector will immediately shift back to minor collections
728after doing one cycle of major collections. 730after doing one major collection.
729 731
730} 732}
731 733
@@ -6404,23 +6406,22 @@ gives the exact number of bytes in use by Lua.
6404Performs a garbage-collection step. 6406Performs a garbage-collection step.
6405This option may be followed by an extra argument, 6407This option may be followed by an extra argument,
6406an integer with the step size. 6408an integer with the step size.
6407The default for this argument is zero.
6408 6409
6409If the size is a positive @id{n}, 6410If the size is a positive @id{n},
6410the collector acts as if @id{n} new objects have been created. 6411the collector acts as if @id{n} new bytes have been allocated.
6411If the size is zero, 6412If the size is zero,
6412the collector performs a basic step. 6413the collector performs a basic step.
6413In incremental mode, 6414In incremental mode,
6414a basic step corresponds to the current step size. 6415a basic step corresponds to the current step size.
6415In generational mode, 6416In generational mode,
6416a basic step performs a full minor collection or 6417a basic step performs a full minor collection or
6417a major collection, 6418an incremental step,
6418if the collector has scheduled one. 6419if the collector has scheduled one.
6419 6420
6420In incremental mode, 6421In incremental mode,
6421the function returns @true if the step finished a collection cycle. 6422the function returns @true if the step finished a collection cycle.
6422In generational mode, 6423In generational mode,
6423the function returns @true if the step performed a major collection. 6424the function returns @true if the step finished a major collection.
6424} 6425}
6425 6426
6426@item{@St{isrunning}| 6427@item{@St{isrunning}|