Thread stacks resized in the atomic phase

Although stack resize can be a little expensive, it seems unusual to
have too many threads needing resize during one GC cycle. On the other
hand, the change allows full collections to skip the propagate phase,
going straight from a pause to the atomic phase.
This commit is contained in:
Roberto Ierusalimschy 2023-07-13 14:55:46 -03:00
parent cbae016202
commit 6b51133a98
1 changed files with 5 additions and 3 deletions

8
lgc.c
View File

@ -638,7 +638,9 @@ static int traversethread (global_State *g, lua_State *th) {
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
markobject(g, uv); /* open upvalues cannot be collected */
if (g->gcstate == GCSatomic) { /* final traversal? */
for (; o < th->stack_last.p + EXTRA_STACK; o++)
if (!g->gcemergency)
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++)
setnilvalue(s2v(o)); /* clear dead stack slice */
/* 'remarkupvals' may have removed thread from 'twups' list */
if (!isintwups(th) && th->openupval != NULL) {
@ -646,8 +648,6 @@ static int traversethread (global_State *g, lua_State *th) {
g->twups = th;
}
}
else if (!g->gcemergency)
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
return 1 + stacksize(th);
}
@ -1710,6 +1710,8 @@ static void fullinc (lua_State *L, global_State *g) {
entersweep(L); /* sweep everything to turn them back to white */
/* finish any pending sweep phase to start a new cycle */
luaC_runtilstate(L, bitmask(GCSpause));
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
g->gcstate = GCSenteratomic; /* go straight to atomic phase ??? */
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
/* estimate must be correct after a full GC cycle */
lua_assert(g->GCestimate == gettotalbytes(g));