From d2c2e32e8a0f649099de0e9d04b5a72037b7b138 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 27 Jul 2020 11:39:42 -0300 Subject: [PATCH] All objects are kept 'new' in incremental GC Small changes to ensure that all objects are kept 'new' in incremental GC (except for fixed strings, which are always old) and to make that fact clearer. --- lfunc.c | 5 +++-- lgc.c | 38 +++++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/lfunc.c b/lfunc.c index 10100e5a..f8c3c446 100644 --- a/lfunc.c +++ b/lfunc.c @@ -234,9 +234,10 @@ int luaF_close (lua_State *L, StkId level, int status) { luaF_unlinkupval(uv); setobj(L, slot, uv->v); /* move value to upvalue slot */ uv->v = slot; /* now current value lives here */ - if (!iswhite(uv)) + if (!iswhite(uv)) { /* neither white nor dead? */ gray2black(uv); /* closed upvalues cannot be gray */ - luaC_barrier(L, uv, slot); + luaC_barrier(L, uv, slot); + } } return status; } diff --git a/lgc.c b/lgc.c index 64d1334b..3591c699 100644 --- a/lgc.c +++ b/lgc.c @@ -60,13 +60,16 @@ #define PAUSEADJ 100 -/* mask to erase all color bits (plus gen. related stuff) */ -#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS | AGEBITS)) +/* mask to erase all color bits */ +#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS)) + +/* mask to erase all GC bits */ +#define maskgcbits (maskcolors & ~AGEBITS) -/* macro to erase all color bits then sets only the current white bit */ +/* macro to erase all color bits then set only the current white bit */ #define makewhite(g,x) \ - (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) + (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) #define white2gray(x) resetbits(x->marked, WHITEBITS) #define black2gray(x) resetbit(x->marked, BLACKBIT) @@ -218,11 +221,12 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { void luaC_barrierback_ (lua_State *L, GCObject *o) { global_State *g = G(L); lua_assert(isblack(o) && !isdead(g, o)); - lua_assert(g->gckind != KGC_GEN || (isold(o) && getage(o) != G_TOUCHED1)); + lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1)); if (getage(o) != G_TOUCHED2) /* not already in gray list? */ linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */ black2gray(o); /* make object gray (again) */ - setage(o, G_TOUCHED1); /* touched in current cycle */ + if (isold(o)) /* generational mode? */ + setage(o, G_TOUCHED1); /* touched in current cycle */ } @@ -341,7 +345,7 @@ static lu_mem markbeingfnz (global_State *g) { static int remarkupvals (global_State *g) { lua_State *thread; lua_State **p = &g->twups; - int work = 0; + int work = 0; /* estimate of how much work was done here */ while ((thread = *p) != NULL) { work++; lua_assert(!isblack(thread)); /* threads are never black */ @@ -777,7 +781,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int countin, freeobj(L, curr); /* erase 'curr' */ } else { /* change mark to 'white' */ - curr->marked = cast_byte((marked & maskcolors) | white); + curr->marked = cast_byte((marked & maskgcbits) | white); p = &curr->next; /* go to next element */ } } @@ -976,10 +980,6 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { static void setpause (global_State *g); -/* mask to erase all color bits, not changing gen-related stuff */ -#define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS)) - - /* ** Sweep a list of objects, deleting dead ones and turning ** the non dead to old (without changing their colors). @@ -1030,9 +1030,12 @@ static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, freeobj(L, curr); /* erase 'curr' */ } else { /* correct mark and age */ - if (getage(curr) == G_NEW) - curr->marked = cast_byte((curr->marked & maskgencolors) | white); - setage(curr, nextage[getage(curr)]); + if (getage(curr) == G_NEW) { /* new objects go back to white */ + int marked = curr->marked & maskgcbits; /* erase GC bits */ + curr->marked = cast_byte(marked | G_SURVIVAL | white); + } + else /* all other objects will be old, and so keep their color */ + setage(curr, nextage[getage(curr)]); p = &curr->next; /* go to next element */ } } @@ -1042,12 +1045,13 @@ static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p, /* ** Traverse a list making all its elements white and clearing their -** age. +** age. In incremental mode, all objects are 'new' all the time, +** except for fixed strings (which are always old). */ static void whitelist (global_State *g, GCObject *p) { int white = luaC_white(g); for (; p != NULL; p = p->next) - p->marked = cast_byte((p->marked & maskcolors) | white); + p->marked = cast_byte((p->marked & maskgcbits) | white); }