aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-27 11:39:42 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-07-27 11:39:42 -0300
commitd2c2e32e8a0f649099de0e9d04b5a72037b7b138 (patch)
tree327d3a7bd2ca97289618a0cb5daf7704ad1d5784
parent8c7c9ea06502b8caa5224bf74c90a8885dbe0d42 (diff)
downloadlua-d2c2e32e8a0f649099de0e9d04b5a72037b7b138.tar.gz
lua-d2c2e32e8a0f649099de0e9d04b5a72037b7b138.tar.bz2
lua-d2c2e32e8a0f649099de0e9d04b5a72037b7b138.zip
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.
-rw-r--r--lfunc.c5
-rw-r--r--lgc.c38
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) {
234 luaF_unlinkupval(uv); 234 luaF_unlinkupval(uv);
235 setobj(L, slot, uv->v); /* move value to upvalue slot */ 235 setobj(L, slot, uv->v); /* move value to upvalue slot */
236 uv->v = slot; /* now current value lives here */ 236 uv->v = slot; /* now current value lives here */
237 if (!iswhite(uv)) 237 if (!iswhite(uv)) { /* neither white nor dead? */
238 gray2black(uv); /* closed upvalues cannot be gray */ 238 gray2black(uv); /* closed upvalues cannot be gray */
239 luaC_barrier(L, uv, slot); 239 luaC_barrier(L, uv, slot);
240 }
240 } 241 }
241 return status; 242 return status;
242} 243}
diff --git a/lgc.c b/lgc.c
index 64d1334b..3591c699 100644
--- a/lgc.c
+++ b/lgc.c
@@ -60,13 +60,16 @@
60#define PAUSEADJ 100 60#define PAUSEADJ 100
61 61
62 62
63/* mask to erase all color bits (plus gen. related stuff) */ 63/* mask to erase all color bits */
64#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS | AGEBITS)) 64#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
65 65
66/* mask to erase all GC bits */
67#define maskgcbits (maskcolors & ~AGEBITS)
66 68
67/* macro to erase all color bits then sets only the current white bit */ 69
70/* macro to erase all color bits then set only the current white bit */
68#define makewhite(g,x) \ 71#define makewhite(g,x) \
69 (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g))) 72 (x->marked = cast_byte((x->marked & maskcolors) | luaC_white(g)))
70 73
71#define white2gray(x) resetbits(x->marked, WHITEBITS) 74#define white2gray(x) resetbits(x->marked, WHITEBITS)
72#define black2gray(x) resetbit(x->marked, BLACKBIT) 75#define black2gray(x) resetbit(x->marked, BLACKBIT)
@@ -218,11 +221,12 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) {
218void luaC_barrierback_ (lua_State *L, GCObject *o) { 221void luaC_barrierback_ (lua_State *L, GCObject *o) {
219 global_State *g = G(L); 222 global_State *g = G(L);
220 lua_assert(isblack(o) && !isdead(g, o)); 223 lua_assert(isblack(o) && !isdead(g, o));
221 lua_assert(g->gckind != KGC_GEN || (isold(o) && getage(o) != G_TOUCHED1)); 224 lua_assert((g->gckind == KGC_GEN) == (isold(o) && getage(o) != G_TOUCHED1));
222 if (getage(o) != G_TOUCHED2) /* not already in gray list? */ 225 if (getage(o) != G_TOUCHED2) /* not already in gray list? */
223 linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */ 226 linkobjgclist(o, g->grayagain); /* link it in 'grayagain' */
224 black2gray(o); /* make object gray (again) */ 227 black2gray(o); /* make object gray (again) */
225 setage(o, G_TOUCHED1); /* touched in current cycle */ 228 if (isold(o)) /* generational mode? */
229 setage(o, G_TOUCHED1); /* touched in current cycle */
226} 230}
227 231
228 232
@@ -341,7 +345,7 @@ static lu_mem markbeingfnz (global_State *g) {
341static int remarkupvals (global_State *g) { 345static int remarkupvals (global_State *g) {
342 lua_State *thread; 346 lua_State *thread;
343 lua_State **p = &g->twups; 347 lua_State **p = &g->twups;
344 int work = 0; 348 int work = 0; /* estimate of how much work was done here */
345 while ((thread = *p) != NULL) { 349 while ((thread = *p) != NULL) {
346 work++; 350 work++;
347 lua_assert(!isblack(thread)); /* threads are never black */ 351 lua_assert(!isblack(thread)); /* threads are never black */
@@ -777,7 +781,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int countin,
777 freeobj(L, curr); /* erase 'curr' */ 781 freeobj(L, curr); /* erase 'curr' */
778 } 782 }
779 else { /* change mark to 'white' */ 783 else { /* change mark to 'white' */
780 curr->marked = cast_byte((marked & maskcolors) | white); 784 curr->marked = cast_byte((marked & maskgcbits) | white);
781 p = &curr->next; /* go to next element */ 785 p = &curr->next; /* go to next element */
782 } 786 }
783 } 787 }
@@ -976,10 +980,6 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
976static void setpause (global_State *g); 980static void setpause (global_State *g);
977 981
978 982
979/* mask to erase all color bits, not changing gen-related stuff */
980#define maskgencolors (~(bitmask(BLACKBIT) | WHITEBITS))
981
982
983/* 983/*
984** Sweep a list of objects, deleting dead ones and turning 984** Sweep a list of objects, deleting dead ones and turning
985** the non dead to old (without changing their colors). 985** the non dead to old (without changing their colors).
@@ -1030,9 +1030,12 @@ static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p,
1030 freeobj(L, curr); /* erase 'curr' */ 1030 freeobj(L, curr); /* erase 'curr' */
1031 } 1031 }
1032 else { /* correct mark and age */ 1032 else { /* correct mark and age */
1033 if (getage(curr) == G_NEW) 1033 if (getage(curr) == G_NEW) { /* new objects go back to white */
1034 curr->marked = cast_byte((curr->marked & maskgencolors) | white); 1034 int marked = curr->marked & maskgcbits; /* erase GC bits */
1035 setage(curr, nextage[getage(curr)]); 1035 curr->marked = cast_byte(marked | G_SURVIVAL | white);
1036 }
1037 else /* all other objects will be old, and so keep their color */
1038 setage(curr, nextage[getage(curr)]);
1036 p = &curr->next; /* go to next element */ 1039 p = &curr->next; /* go to next element */
1037 } 1040 }
1038 } 1041 }
@@ -1042,12 +1045,13 @@ static GCObject **sweepgen (lua_State *L, global_State *g, GCObject **p,
1042 1045
1043/* 1046/*
1044** Traverse a list making all its elements white and clearing their 1047** Traverse a list making all its elements white and clearing their
1045** age. 1048** age. In incremental mode, all objects are 'new' all the time,
1049** except for fixed strings (which are always old).
1046*/ 1050*/
1047static void whitelist (global_State *g, GCObject *p) { 1051static void whitelist (global_State *g, GCObject *p) {
1048 int white = luaC_white(g); 1052 int white = luaC_white(g);
1049 for (; p != NULL; p = p->next) 1053 for (; p != NULL; p = p->next)
1050 p->marked = cast_byte((p->marked & maskcolors) | white); 1054 p->marked = cast_byte((p->marked & maskgcbits) | white);
1051} 1055}
1052 1056
1053 1057