diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-27 11:39:42 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-27 11:39:42 -0300 |
commit | d2c2e32e8a0f649099de0e9d04b5a72037b7b138 (patch) | |
tree | 327d3a7bd2ca97289618a0cb5daf7704ad1d5784 | |
parent | 8c7c9ea06502b8caa5224bf74c90a8885dbe0d42 (diff) | |
download | lua-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.c | 5 | ||||
-rw-r--r-- | lgc.c | 38 |
2 files changed, 24 insertions, 19 deletions
@@ -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 | } |
@@ -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) { | |||
218 | void luaC_barrierback_ (lua_State *L, GCObject *o) { | 221 | void 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) { | |||
341 | static int remarkupvals (global_State *g) { | 345 | static 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) { | |||
976 | static void setpause (global_State *g); | 980 | static 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 | */ |
1047 | static void whitelist (global_State *g, GCObject *p) { | 1051 | static 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 | ||