diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-10 15:23:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-10 15:23:45 -0300 |
commit | 1c1a98e872ad09b12fe2085031f0045f993ca5f0 (patch) | |
tree | a711825a8b3f991797ef19dfaad083acbf59189a | |
parent | c006f085d98923e505c7fe8909944d3c182f8301 (diff) | |
download | lua-1c1a98e872ad09b12fe2085031f0045f993ca5f0.tar.gz lua-1c1a98e872ad09b12fe2085031f0045f993ca5f0.tar.bz2 lua-1c1a98e872ad09b12fe2085031f0045f993ca5f0.zip |
corrected some places where an old object could end up in front
of a new one + minimal documentation about this problem
-rw-r--r-- | lfunc.c | 8 | ||||
-rw-r--r-- | lgc.c | 9 | ||||
-rw-r--r-- | lgc.h | 5 | ||||
-rw-r--r-- | lstring.c | 3 |
4 files changed, 15 insertions, 10 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 2.22 2010/04/29 17:34:35 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 2.23 2010/04/29 21:43:36 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -52,12 +52,14 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
52 | UpVal *p; | 52 | UpVal *p; |
53 | UpVal *uv; | 53 | UpVal *uv; |
54 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { | 54 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { |
55 | GCObject *o = obj2gco(p); | ||
55 | lua_assert(p->v != &p->u.value); | 56 | lua_assert(p->v != &p->u.value); |
56 | if (p->v == level) { /* found a corresponding upvalue? */ | 57 | if (p->v == level) { /* found a corresponding upvalue? */ |
57 | if (isdead(g, obj2gco(p))) /* is it dead? */ | 58 | if (isdead(g, o)) /* is it dead? */ |
58 | changewhite(obj2gco(p)); /* ressurrect it */ | 59 | changewhite(o); /* ressurrect it */ |
59 | return p; | 60 | return p; |
60 | } | 61 | } |
62 | resetoldbit(o); /* may create a newer upval after this one */ | ||
61 | pp = &p->next; | 63 | pp = &p->next; |
62 | } | 64 | } |
63 | /* not found: create a new one */ | 65 | /* not found: create a new one */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.92 2010/05/07 18:43:24 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.93 2010/05/10 16:46:49 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -164,7 +164,7 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) { | |||
164 | lua_assert(!isblack(o)); /* open upvalues are never black */ | 164 | lua_assert(!isblack(o)); /* open upvalues are never black */ |
165 | if (isgray(o)) { | 165 | if (isgray(o)) { |
166 | if (keepinvariant(g)) { | 166 | if (keepinvariant(g)) { |
167 | resetoldbit(o); | 167 | resetoldbit(o); /* see MOVE OLD rule */ |
168 | gray2black(o); /* it is being visited now */ | 168 | gray2black(o); /* it is being visited now */ |
169 | markvalue(g, uv->v); | 169 | markvalue(g, uv->v); |
170 | } | 170 | } |
@@ -670,6 +670,7 @@ static Udata *udata2finalize (global_State *g) { | |||
670 | u->uv.next = g->allgc; /* return it to 'allgc' list */ | 670 | u->uv.next = g->allgc; /* return it to 'allgc' list */ |
671 | g->allgc = o; | 671 | g->allgc = o; |
672 | resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | 672 | resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ |
673 | resetoldbit(o); /* see MOVE OLD rule */ | ||
673 | if (!keepinvariant(g)) /* not keeping invariant? */ | 674 | if (!keepinvariant(g)) /* not keeping invariant? */ |
674 | makewhite(g, o); /* "sweep" object */ | 675 | makewhite(g, o); /* "sweep" object */ |
675 | return u; | 676 | return u; |
@@ -729,7 +730,6 @@ void luaC_separateudata (lua_State *L, int all) { | |||
729 | p = &gch(curr)->next; /* don't bother with it */ | 730 | p = &gch(curr)->next; /* don't bother with it */ |
730 | else { | 731 | else { |
731 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 732 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
732 | resetoldbit(curr); /* may be old when 'all' is true */ | ||
733 | *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ | 733 | *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ |
734 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | 734 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
735 | *lastnext = curr; | 735 | *lastnext = curr; |
@@ -756,7 +756,7 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) { | |||
756 | u->uv.next = g->udgc; /* link it in list 'udgc' */ | 756 | u->uv.next = g->udgc; /* link it in list 'udgc' */ |
757 | g->udgc = obj2gco(u); | 757 | g->udgc = obj2gco(u); |
758 | l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ | 758 | l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ |
759 | resetoldbit(obj2gco(u)); | 759 | resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ |
760 | } | 760 | } |
761 | } | 761 | } |
762 | 762 | ||
@@ -854,7 +854,6 @@ static void atomic (lua_State *L) { | |||
854 | 854 | ||
855 | static l_mem singlestep (lua_State *L) { | 855 | static l_mem singlestep (lua_State *L) { |
856 | global_State *g = G(L); | 856 | global_State *g = G(L); |
857 | /*lua_checkmemory(L);*/ | ||
858 | switch (g->gcstate) { | 857 | switch (g->gcstate) { |
859 | case GCSpause: { | 858 | case GCSpause: { |
860 | if (!isgenerational(g)) | 859 | if (!isgenerational(g)) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.39 2010/05/07 18:43:51 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.40 2010/05/10 16:46:49 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -91,6 +91,9 @@ | |||
91 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | 91 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) |
92 | 92 | ||
93 | #define isold(x) testbit((x)->gch.marked, OLDBIT) | 93 | #define isold(x) testbit((x)->gch.marked, OLDBIT) |
94 | |||
95 | /* MOVE OLD rule: whenever an object is moved to the beginning of | ||
96 | a GC list, its old bit must be cleared */ | ||
94 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) | 97 | #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) |
95 | 98 | ||
96 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | 99 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.16 2009/12/16 16:42:58 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.17 2010/04/03 20:24:18 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,6 +37,7 @@ void luaS_resize (lua_State *L, int newsize) { | |||
37 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ | 37 | unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ |
38 | gch(p)->next = tb->hash[h]; /* chain it */ | 38 | gch(p)->next = tb->hash[h]; /* chain it */ |
39 | tb->hash[h] = p; | 39 | tb->hash[h] = p; |
40 | resetoldbit(p); /* see MOVE OLD rule */ | ||
40 | p = next; | 41 | p = next; |
41 | } | 42 | } |
42 | } | 43 | } |