diff options
-rw-r--r-- | lgc.c | 19 | ||||
-rw-r--r-- | lgc.h | 10 | ||||
-rw-r--r-- | lstate.h | 8 | ||||
-rw-r--r-- | ltests.c | 8 |
4 files changed, 20 insertions, 25 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.146 2013/08/16 18:55:49 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.147 2013/08/19 14:18:43 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 | */ |
@@ -65,8 +65,6 @@ | |||
65 | 65 | ||
66 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | 66 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) |
67 | 67 | ||
68 | #define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) | ||
69 | |||
70 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) | 68 | #define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) |
71 | 69 | ||
72 | 70 | ||
@@ -764,11 +762,11 @@ static void checkSizes (lua_State *L) { | |||
764 | 762 | ||
765 | static GCObject *udata2finalize (global_State *g) { | 763 | static GCObject *udata2finalize (global_State *g) { |
766 | GCObject *o = g->tobefnz; /* get first element */ | 764 | GCObject *o = g->tobefnz; /* get first element */ |
767 | lua_assert(isfinalized(o)); | 765 | lua_assert(tofinalize(o)); |
768 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ | 766 | g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ |
769 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ | 767 | gch(o)->next = g->allgc; /* return it to 'allgc' list */ |
770 | g->allgc = o; | 768 | g->allgc = o; |
771 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | 769 | resetbit(gch(o)->marked, FINALIZEDBIT); /* object is back in 'allgc' */ |
772 | if (!keepinvariant(g)) /* not keeping invariant? */ | 770 | if (!keepinvariant(g)) /* not keeping invariant? */ |
773 | makewhite(g, o); /* "sweep" object */ | 771 | makewhite(g, o); /* "sweep" object */ |
774 | return o; | 772 | return o; |
@@ -826,12 +824,10 @@ static void separatetobefnz (lua_State *L, int all) { | |||
826 | while (*lastnext != NULL) | 824 | while (*lastnext != NULL) |
827 | lastnext = &gch(*lastnext)->next; | 825 | lastnext = &gch(*lastnext)->next; |
828 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | 826 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
829 | lua_assert(!isfinalized(curr)); | 827 | lua_assert(tofinalize(curr)); |
830 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | ||
831 | if (!(iswhite(curr) || all)) /* not being collected? */ | 828 | if (!(iswhite(curr) || all)) /* not being collected? */ |
832 | p = &gch(curr)->next; /* don't bother with it */ | 829 | p = &gch(curr)->next; /* don't bother with it */ |
833 | else { | 830 | else { |
834 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | ||
835 | *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ | 831 | *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ |
836 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ | 832 | gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ |
837 | *lastnext = curr; | 833 | *lastnext = curr; |
@@ -847,9 +843,8 @@ static void separatetobefnz (lua_State *L, int all) { | |||
847 | */ | 843 | */ |
848 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | 844 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { |
849 | global_State *g = G(L); | 845 | global_State *g = G(L); |
850 | if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ | 846 | if (tofinalize(o) || /* obj. is already marked... */ |
851 | isfinalized(o) || /* ... or is finalized... */ | 847 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ |
852 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ | ||
853 | return; /* nothing to be done */ | 848 | return; /* nothing to be done */ |
854 | else { /* move 'o' to 'finobj' list */ | 849 | else { /* move 'o' to 'finobj' list */ |
855 | GCObject **p; | 850 | GCObject **p; |
@@ -863,7 +858,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
863 | *p = ho->next; /* remove 'o' from root list */ | 858 | *p = ho->next; /* remove 'o' from root list */ |
864 | ho->next = g->finobj; /* link it in list 'finobj' */ | 859 | ho->next = g->finobj; /* link it in list 'finobj' */ |
865 | g->finobj = o; | 860 | g->finobj = o; |
866 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ | 861 | l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ |
867 | if (!keepinvariant(g)) /* not keeping invariant? */ | 862 | if (!keepinvariant(g)) /* not keeping invariant? */ |
868 | makewhite(g, o); /* "sweep" object */ | 863 | makewhite(g, o); /* "sweep" object */ |
869 | } | 864 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.61 2013/08/16 18:55:49 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.62 2013/08/19 14:18:43 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 | */ |
@@ -76,10 +76,9 @@ | |||
76 | #define WHITE0BIT 0 /* object is white (type 0) */ | 76 | #define WHITE0BIT 0 /* object is white (type 0) */ |
77 | #define WHITE1BIT 1 /* object is white (type 1) */ | 77 | #define WHITE1BIT 1 /* object is white (type 1) */ |
78 | #define BLACKBIT 2 /* object is black */ | 78 | #define BLACKBIT 2 /* object is black */ |
79 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ | 79 | #define FINALIZEDBIT 3 /* object has been marked for finalization */ |
80 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ | 80 | #define FIXEDBIT 4 /* object is fixed (should not be collected) */ |
81 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ | 81 | #define LOCALBIT 5 /* object is not local */ |
82 | #define LOCALBIT 6 /* object is not local */ | ||
83 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | 82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
84 | 83 | ||
85 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
@@ -91,6 +90,7 @@ | |||
91 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | 90 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) |
92 | #define islocal(x) (!testbit((x)->gch.marked, LOCALBIT)) | 91 | #define islocal(x) (!testbit((x)->gch.marked, LOCALBIT)) |
93 | 92 | ||
93 | #define tofinalize(x) testbit((x)->gch.marked, FINALIZEDBIT) | ||
94 | 94 | ||
95 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | 95 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
96 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) | 96 | #define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.83 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.84 2013/08/07 12:18:11 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -33,9 +33,9 @@ | |||
33 | ** threads, but the thread may already be dead, while the upvalue is | 33 | ** threads, but the thread may already be dead, while the upvalue is |
34 | ** still accessible through closures.) | 34 | ** still accessible through closures.) |
35 | ** | 35 | ** |
36 | ** Objects with finalizers are kept in the list g->finobj. | 36 | ** Live objects with finalizers are kept in the list g->finobj. The |
37 | ** | 37 | ** list g->tobefnz links all objects being finalized. In particular, an |
38 | ** The list g->tobefnz links all objects being finalized. | 38 | ** object has its FINALIZEDBIT set iff it is in one of these lists. |
39 | 39 | ||
40 | */ | 40 | */ |
41 | 41 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.144 2013/08/18 16:12:18 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.145 2013/08/19 14:16:33 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -466,12 +466,12 @@ int lua_checkmemory (lua_State *L) { | |||
466 | if (gch(o)->tt == LUA_TTHREAD) isthread = 1; /* now travesing threads... */ | 466 | if (gch(o)->tt == LUA_TTHREAD) isthread = 1; /* now travesing threads... */ |
467 | else lua_assert(!isthread); /* ... and only threads */ | 467 | else lua_assert(!isthread); /* ... and only threads */ |
468 | checkobject(g, o, maybedead); | 468 | checkobject(g, o, maybedead); |
469 | lua_assert(!testbit(o->gch.marked, SEPARATED)); | 469 | lua_assert(!tofinalize(o)); |
470 | } | 470 | } |
471 | /* check 'finobj' list */ | 471 | /* check 'finobj' list */ |
472 | checkgray(g, g->finobj); | 472 | checkgray(g, g->finobj); |
473 | for (o = g->finobj; o != NULL; o = gch(o)->next) { | 473 | for (o = g->finobj; o != NULL; o = gch(o)->next) { |
474 | lua_assert(testbit(o->gch.marked, SEPARATED)); | 474 | lua_assert(tofinalize(o)); |
475 | lua_assert(gch(o)->tt == LUA_TUSERDATA || | 475 | lua_assert(gch(o)->tt == LUA_TUSERDATA || |
476 | gch(o)->tt == LUA_TTABLE); | 476 | gch(o)->tt == LUA_TTABLE); |
477 | checkobject(g, o, 0); | 477 | checkobject(g, o, 0); |
@@ -480,7 +480,7 @@ int lua_checkmemory (lua_State *L) { | |||
480 | checkgray(g, g->tobefnz); | 480 | checkgray(g, g->tobefnz); |
481 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { | 481 | for (o = g->tobefnz; o != NULL; o = gch(o)->next) { |
482 | lua_assert(!iswhite(o) || g->gcstate == GCSpause); | 482 | lua_assert(!iswhite(o) || g->gcstate == GCSpause); |
483 | lua_assert(!isdead(g, o) && testbit(o->gch.marked, SEPARATED)); | 483 | lua_assert(!isdead(g, o) && tofinalize(o)); |
484 | lua_assert(gch(o)->tt == LUA_TUSERDATA || | 484 | lua_assert(gch(o)->tt == LUA_TUSERDATA || |
485 | gch(o)->tt == LUA_TTABLE); | 485 | gch(o)->tt == LUA_TTABLE); |
486 | } | 486 | } |