mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
'objsize' broke in smaller pieces
This commit is contained in:
parent
e4f418f07c
commit
3d54b42d59
15
lfunc.c
15
lfunc.c
@ -264,6 +264,21 @@ Proto *luaF_newproto (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
size_t luaF_protosize (Proto *p) {
|
||||
size_t sz = sizeof(Proto)
|
||||
+ cast_uint(p->sizep) * sizeof(Proto*)
|
||||
+ cast_uint(p->sizek) * sizeof(TValue)
|
||||
+ cast_uint(p->sizelocvars) * sizeof(LocVar)
|
||||
+ cast_uint(p->sizeupvalues) * sizeof(Upvaldesc);
|
||||
if (!(p->flag & PF_FIXED)) {
|
||||
sz += cast_uint(p->sizecode) * sizeof(Instruction)
|
||||
+ cast_uint(p->sizelineinfo) * sizeof(lu_byte)
|
||||
+ cast_uint(p->sizeabslineinfo) * sizeof(AbsLineInfo);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
void luaF_freeproto (lua_State *L, Proto *f) {
|
||||
if (!(f->flag & PF_FIXED)) {
|
||||
luaM_freearray(L, f->code, cast_sizet(f->sizecode));
|
||||
|
1
lfunc.h
1
lfunc.h
@ -56,6 +56,7 @@ LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
|
||||
LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level);
|
||||
LUAI_FUNC StkId luaF_close (lua_State *L, StkId level, int status, int yy);
|
||||
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
|
||||
LUAI_FUNC size_t luaF_protosize (Proto *p);
|
||||
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
|
||||
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
|
||||
int pc);
|
||||
|
58
lgc.c
58
lgc.c
@ -113,13 +113,7 @@ static void entersweep (lua_State *L);
|
||||
static size_t objsize (GCObject *o) {
|
||||
switch (o->tt) {
|
||||
case LUA_VTABLE: {
|
||||
/* Fow now, table size does not consider 'haslastfree' */
|
||||
Table *t = gco2t(o);
|
||||
size_t sz = sizeof(Table)
|
||||
+ luaH_realasize(t) * (sizeof(Value) + 1);
|
||||
if (!isdummy(t))
|
||||
sz += sizenode(t) * sizeof(Node);
|
||||
return sz;
|
||||
return luaH_size(gco2t(o));
|
||||
}
|
||||
case LUA_VLCL: {
|
||||
LClosure *cl = gco2lcl(o);
|
||||
@ -135,26 +129,10 @@ static size_t objsize (GCObject *o) {
|
||||
return sizeudata(u->nuvalue, u->len);
|
||||
}
|
||||
case LUA_VPROTO: {
|
||||
Proto *p = gco2p(o);
|
||||
size_t sz = sizeof(Proto)
|
||||
+ cast_uint(p->sizep) * sizeof(Proto*)
|
||||
+ cast_uint(p->sizek) * sizeof(TValue)
|
||||
+ cast_uint(p->sizelocvars) * sizeof(LocVar)
|
||||
+ cast_uint(p->sizeupvalues) * sizeof(Upvaldesc);
|
||||
if (!(p->flag & PF_FIXED)) {
|
||||
sz += cast_uint(p->sizecode) * sizeof(Instruction)
|
||||
+ cast_uint(p->sizelineinfo) * sizeof(lu_byte)
|
||||
+ cast_uint(p->sizeabslineinfo) * sizeof(AbsLineInfo);
|
||||
}
|
||||
return sz;
|
||||
return luaF_protosize(gco2p(o));
|
||||
}
|
||||
case LUA_VTHREAD: {
|
||||
lua_State *L1 = gco2th(o);
|
||||
size_t sz = sizeof(lua_State) + LUA_EXTRASPACE
|
||||
+ cast_uint(L1->nci) * sizeof(CallInfo);
|
||||
if (L1->stack.p != NULL)
|
||||
sz += cast_uint(stacksize(L1) + EXTRA_STACK) * sizeof(StackValue);
|
||||
return sz;
|
||||
return luaE_statesize(gco2th(o));
|
||||
}
|
||||
case LUA_VSHRSTR: {
|
||||
TString *ts = gco2ts(o);
|
||||
@ -164,7 +142,9 @@ static size_t objsize (GCObject *o) {
|
||||
TString *ts = gco2ts(o);
|
||||
return luaS_sizelngstr(ts->u.lnglen, ts->shrlen);
|
||||
}
|
||||
case LUA_VUPVAL: return sizeof(UpVal);
|
||||
case LUA_VUPVAL: {
|
||||
return sizeof(UpVal);
|
||||
}
|
||||
default: lua_assert(0); return 0;
|
||||
}
|
||||
}
|
||||
@ -615,7 +595,7 @@ static l_mem traversetable (global_State *g, Table *h) {
|
||||
}
|
||||
else /* not weak */
|
||||
traversestrongtable(g, h);
|
||||
return 1 + sizenode(h) + h->alimit;
|
||||
return 1 + 2*sizenode(h) + h->alimit;
|
||||
}
|
||||
|
||||
|
||||
@ -1291,10 +1271,11 @@ static void minor2inc (lua_State *L, global_State *g, lu_byte kind) {
|
||||
/*
|
||||
** Decide whether to shift to major mode. It tests two conditions:
|
||||
** 1) Whether the number of added old objects in this collection is more
|
||||
** than half the number of new objects. ('step' is the number of objects
|
||||
** created between minor collections. Except for forward barriers, it
|
||||
** is the maximum number of objects that can become old in each minor
|
||||
** collection.)
|
||||
** than half the number of new objects. ('step' is equal to the debt set
|
||||
** to trigger the next minor collection; that is equal to the number
|
||||
** of objects created since the previous minor collection. Except for
|
||||
** forward barriers, it is the maximum number of objects that can become
|
||||
** old in each minor collection.)
|
||||
** 2) Whether the accumulated number of added old objects is larger
|
||||
** than 'minormajor'% of the number of lived objects after the last
|
||||
** major collection. (That percentage is computed in 'limit'.)
|
||||
@ -1678,7 +1659,7 @@ void luaC_runtilstate (lua_State *L, int state, int fast) {
|
||||
|
||||
|
||||
/*
|
||||
** Performs a basic incremental step. The debt and step size are
|
||||
** Performs a basic incremental step. The step size is
|
||||
** converted from bytes to "units of work"; then the function loops
|
||||
** running single steps until adding that many units of work or
|
||||
** finishing a cycle (pause state). Finally, it sets the debt that
|
||||
@ -1689,7 +1670,9 @@ static void incstep (lua_State *L, global_State *g) {
|
||||
l_mem work2do = applygcparam(g, STEPMUL, stepsize);
|
||||
l_mem stres;
|
||||
int fast = (work2do == 0); /* special case: do a full collection */
|
||||
//printf("\n** %ld %ld %d\n", work2do, stepsize, g->gcstate);
|
||||
do { /* repeat until enough work */
|
||||
//printf("%d-", g->gcstate);
|
||||
stres = singlestep(L, fast); /* perform one single step */
|
||||
if (stres == step2minor) /* returned to minor collections? */
|
||||
return; /* nothing else to be done here */
|
||||
@ -1716,21 +1699,20 @@ void luaC_step (lua_State *L) {
|
||||
if (!gcrunning(g)) /* not running? */
|
||||
luaE_setdebt(g, 20000);
|
||||
else {
|
||||
// printf("mem: %ld kind: %s ", gettotalbytes(g),
|
||||
// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
|
||||
// "genminor");
|
||||
//printf("mem: %ld kind: %s ", gettotalbytes(g),
|
||||
// g->gckind == KGC_INC ? "inc" : g->gckind == KGC_GENMAJOR ? "genmajor" :
|
||||
// "genminor");
|
||||
switch (g->gckind) {
|
||||
case KGC_INC: case KGC_GENMAJOR:
|
||||
// printf("(%d -> ", g->gcstate);
|
||||
incstep(L, g);
|
||||
// printf("%d) ", g->gcstate);
|
||||
//printf("%d) ", g->gcstate);
|
||||
break;
|
||||
case KGC_GENMINOR:
|
||||
youngcollection(L, g);
|
||||
setminordebt(g);
|
||||
break;
|
||||
}
|
||||
// printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
|
||||
//printf("-> mem: %ld debt: %ld\n", gettotalbytes(g), g->GCdebt);
|
||||
}
|
||||
}
|
||||
|
||||
|
15
lgc.h
15
lgc.h
@ -160,7 +160,11 @@
|
||||
*/
|
||||
|
||||
|
||||
/* Default Values for GC parameters */
|
||||
/*
|
||||
** {======================================================
|
||||
** Default Values for GC parameters
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** Minor collections will shift to major ones after LUAI_MINORMAJOR%
|
||||
@ -189,17 +193,20 @@
|
||||
/*
|
||||
** Step multiplier: The collector handles LUAI_GCMUL% work units for
|
||||
** each new allocated byte. (Each "work unit" corresponds roughly to
|
||||
** sweeping or marking one object.)
|
||||
** sweeping one object or traversing one slot.)
|
||||
*/
|
||||
#define LUAI_GCMUL 20 /* ??? */
|
||||
#define LUAI_GCMUL 40
|
||||
|
||||
/* How many bytes to allocate before next GC step */
|
||||
#define LUAI_GCSTEPSIZE (250 * sizeof(void*))
|
||||
#define LUAI_GCSTEPSIZE (200 * sizeof(Table))
|
||||
|
||||
|
||||
#define setgcparam(g,p,v) (g->gcparams[LUA_GCP##p] = luaO_codeparam(v))
|
||||
#define applygcparam(g,p,x) luaO_applyparam(g->gcparams[LUA_GCP##p], x)
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
|
||||
/*
|
||||
** Control when GC is running:
|
||||
*/
|
||||
|
8
lstate.c
8
lstate.c
@ -257,6 +257,14 @@ static void preinit_thread (lua_State *L, global_State *g) {
|
||||
}
|
||||
|
||||
|
||||
size_t luaE_statesize (lua_State *L) {
|
||||
size_t sz = sizeof(LG) + cast_uint(L->nci) * sizeof(CallInfo);
|
||||
if (L->stack.p != NULL)
|
||||
sz += cast_uint(stacksize(L) + EXTRA_STACK) * sizeof(StackValue);
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
static void close_state (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
if (!completestate(g)) /* closing a partially built state? */
|
||||
|
1
lstate.h
1
lstate.h
@ -416,6 +416,7 @@ union GCUnion {
|
||||
|
||||
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
|
||||
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
|
||||
LUAI_FUNC size_t luaE_statesize (lua_State *L);
|
||||
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
|
||||
LUAI_FUNC void luaE_shrinkCI (lua_State *L);
|
||||
LUAI_FUNC void luaE_checkcstack (lua_State *L);
|
||||
|
12
ltable.c
12
ltable.c
@ -805,6 +805,18 @@ Table *luaH_new (lua_State *L) {
|
||||
}
|
||||
|
||||
|
||||
size_t luaH_size (Table *t) {
|
||||
size_t sz = sizeof(Table)
|
||||
+ luaH_realasize(t) * (sizeof(Value) + 1);
|
||||
if (!isdummy(t)) {
|
||||
sz += sizenode(t) * sizeof(Node);
|
||||
if (haslastfree(t))
|
||||
sz += sizeof(Limbox);
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Frees a table.
|
||||
*/
|
||||
|
1
ltable.h
1
ltable.h
@ -163,6 +163,7 @@ LUAI_FUNC Table *luaH_new (lua_State *L);
|
||||
LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned nasize,
|
||||
unsigned nhsize);
|
||||
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned nasize);
|
||||
LUAI_FUNC size_t luaH_size (Table *t);
|
||||
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
|
||||
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
|
||||
LUAI_FUNC lua_Unsigned luaH_getn (Table *t);
|
||||
|
@ -608,8 +608,8 @@ An object is considered @def{dead}
|
||||
as soon as the collector can be sure the object
|
||||
will not be accessed again in the normal execution of the program.
|
||||
(@Q{Normal execution} here excludes finalizers,
|
||||
which can resurrect dead objects @see{finalizers},
|
||||
and excludes also operations using the debug library.)
|
||||
which resurrect dead objects @see{finalizers},
|
||||
and it excludes also some operations using the debug library.)
|
||||
Note that the time when the collector can be sure that an object
|
||||
is dead may not coincide with the programmer's expectations.
|
||||
The only guarantees are that Lua will not collect an object
|
||||
@ -657,25 +657,27 @@ and the @def{garbage-collector step size}.
|
||||
|
||||
The garbage-collector pause
|
||||
controls how long the collector waits before starting a new cycle.
|
||||
The collector starts a new cycle when the number of objects
|
||||
The collector starts a new cycle when the number of bytes
|
||||
hits @M{n%} of the total after the previous collection.
|
||||
Larger values make the collector less aggressive.
|
||||
Values equal to or less than 100 mean the collector will not wait to
|
||||
start a new cycle.
|
||||
A value of 200 means that the collector waits for
|
||||
the total number of objects to double before starting a new cycle.
|
||||
the total number of bytes to double before starting a new cycle.
|
||||
|
||||
The garbage-collector step size controls the
|
||||
size of each incremental step,
|
||||
specifically how many objects the interpreter creates
|
||||
specifically how many bytes the interpreter allocates
|
||||
before performing a step:
|
||||
A value of @M{n} means the interpreter will create
|
||||
approximately @M{n} objects between steps.
|
||||
A value of @M{n} means the interpreter will allocate
|
||||
approximately @M{n} bytes between steps.
|
||||
|
||||
The garbage-collector step multiplier
|
||||
controls the size of each GC step.
|
||||
A value of @M{n} means the interpreter will mark or sweep,
|
||||
in each step, @M{n%} objects for each created object.
|
||||
controls how much work each incremental step does.
|
||||
A value of @M{n} means the interpreter will execute
|
||||
@M{n%} @emphx{units of work} for each byte allocated.
|
||||
A unit of work corresponds roughly to traversing one slot
|
||||
or sweeping one object.
|
||||
Larger values make the collector more aggressive.
|
||||
Beware that values too small can
|
||||
make the collector too slow to ever finish a cycle.
|
||||
@ -689,7 +691,7 @@ effectively producing a non-incremental, stop-the-world collector.
|
||||
In generational mode,
|
||||
the collector does frequent @emph{minor} collections,
|
||||
which traverses only objects recently created.
|
||||
If after a minor collection the number of objects is above a limit,
|
||||
If after a minor collection the number of bytes is above a limit,
|
||||
the collector shifts to a @emph{major} collection,
|
||||
which traverses all objects.
|
||||
The collector will then stay doing major collections until
|
||||
@ -702,30 +704,30 @@ and the @def{major-minor multiplier}.
|
||||
|
||||
The minor multiplier controls the frequency of minor collections.
|
||||
For a minor multiplier @M{x},
|
||||
a new minor collection will be done when the number of objects
|
||||
a new minor collection will be done when the number of bytes
|
||||
grows @M{x%} larger than the number in use just
|
||||
after the last major collection.
|
||||
For instance, for a multiplier of 20,
|
||||
the collector will do a minor collection when the number of objects
|
||||
the collector will do a minor collection when the number of bytes
|
||||
gets 20% larger than the total after the last major collection.
|
||||
|
||||
The minor-major multiplier controls the shift to major collections.
|
||||
For a multiplier @M{x},
|
||||
the collector will shift to a major collection
|
||||
when the number of old objects grows @M{x%} larger
|
||||
when the number of bytes from old objects grows @M{x%} larger
|
||||
than the total after the previous major collection.
|
||||
For instance, for a multiplier of 100,
|
||||
the collector will do a major collection when the number of old objects
|
||||
the collector will do a major collection when the number of old bytes
|
||||
gets larger than twice the total after the previous major collection.
|
||||
|
||||
The major-minor multiplier controls the shift back to minor collections.
|
||||
For a multiplier @M{x},
|
||||
the collector will shift back to minor collections
|
||||
after a major collection collects at least @M{x%}
|
||||
of the objects allocated during the last cycle.
|
||||
of the bytes allocated during the last cycle.
|
||||
In particular, for a multiplier of 0,
|
||||
the collector will immediately shift back to minor collections
|
||||
after doing one cycle of major collections.
|
||||
after doing one major collection.
|
||||
|
||||
}
|
||||
|
||||
@ -6404,23 +6406,22 @@ gives the exact number of bytes in use by Lua.
|
||||
Performs a garbage-collection step.
|
||||
This option may be followed by an extra argument,
|
||||
an integer with the step size.
|
||||
The default for this argument is zero.
|
||||
|
||||
If the size is a positive @id{n},
|
||||
the collector acts as if @id{n} new objects have been created.
|
||||
the collector acts as if @id{n} new bytes have been allocated.
|
||||
If the size is zero,
|
||||
the collector performs a basic step.
|
||||
In incremental mode,
|
||||
a basic step corresponds to the current step size.
|
||||
In generational mode,
|
||||
a basic step performs a full minor collection or
|
||||
a major collection,
|
||||
an incremental step,
|
||||
if the collector has scheduled one.
|
||||
|
||||
In incremental mode,
|
||||
the function returns @true if the step finished a collection cycle.
|
||||
In generational mode,
|
||||
the function returns @true if the step performed a major collection.
|
||||
the function returns @true if the step finished a major collection.
|
||||
}
|
||||
|
||||
@item{@St{isrunning}|
|
||||
|
Loading…
x
Reference in New Issue
Block a user