diff options
-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 | ||