aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c21
-rw-r--r--lgc.h9
-rw-r--r--lstate.c20
-rw-r--r--lstate.h25
-rw-r--r--ltests.c19
5 files changed, 47 insertions, 47 deletions
diff --git a/lgc.c b/lgc.c
index c6f40a33..355c1003 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.160 2013/09/11 12:47:48 roberto Exp roberto $ 2** $Id: lgc.c,v 2.161 2013/09/11 13:24:55 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*/
@@ -304,7 +304,7 @@ static void markbeingfnz (global_State *g) {
304** thread.) 304** thread.)
305*/ 305*/
306static void remarkupvals (global_State *g) { 306static void remarkupvals (global_State *g) {
307 GCObject *thread = hvalue(&g->l_registry)->next; 307 GCObject *thread = g->mainthread->next;
308 for (; thread != NULL; thread = gch(thread)->next) { 308 for (; thread != NULL; thread = gch(thread)->next) {
309 lua_assert(!isblack(thread)); /* threads are never black */ 309 lua_assert(!isblack(thread)); /* threads are never black */
310 if (!isgray(thread)) { /* dead thread? */ 310 if (!isgray(thread)) { /* dead thread? */
@@ -933,10 +933,9 @@ static void localmarkthread (lua_State *l) {
933** a thread) 933** a thread)
934*/ 934*/
935static void localmark (global_State *g) { 935static void localmark (global_State *g) {
936 GCObject *thread = hvalue(&g->l_registry)->next; 936 GCObject *thread = obj2gco(g->mainthread);
937 for (; thread != NULL; thread = gch(thread)->next) /* traverse all threads */ 937 for (; thread != NULL; thread = gch(thread)->next) /* traverse all threads */
938 localmarkthread(gco2th(thread)); 938 localmarkthread(gco2th(thread));
939 localmarkthread(g->mainthread);
940} 939}
941 940
942 941
@@ -1057,12 +1056,14 @@ void luaC_freeallobjects (lua_State *L) {
1057 separatetobefnz(g, 1); /* separate all objects with finalizers */ 1056 separatetobefnz(g, 1); /* separate all objects with finalizers */
1058 lua_assert(g->finobj == NULL && g->localfin == NULL); 1057 lua_assert(g->finobj == NULL && g->localfin == NULL);
1059 callallpendingfinalizers(L, 0); 1058 callallpendingfinalizers(L, 0);
1059 lua_assert(g->tobefnz == NULL);
1060 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ 1060 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
1061 g->gckind = KGC_NORMAL; 1061 g->gckind = KGC_NORMAL;
1062 sweepwholelist(L, &g->localgc);
1062 sweepwholelist(L, &g->localfin); /* finalizers can create objs. with fins. */ 1063 sweepwholelist(L, &g->localfin); /* finalizers can create objs. with fins. */
1063 sweepwholelist(L, &g->finobj); 1064 sweepwholelist(L, &g->finobj);
1064 sweepwholelist(L, &g->localgc);
1065 sweepwholelist(L, &g->allgc); 1065 sweepwholelist(L, &g->allgc);
1066 sweepwholelist(L, &g->mainthread->next);
1066 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */ 1067 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
1067 lua_assert(g->strt.nuse == 0); 1068 lua_assert(g->strt.nuse == 0);
1068} 1069}
@@ -1163,11 +1164,13 @@ static lu_mem singlestep (lua_State *L) {
1163 return sweepstep(L, g, GCSsweeptobefnz, &g->tobefnz); 1164 return sweepstep(L, g, GCSsweeptobefnz, &g->tobefnz);
1164 } 1165 }
1165 case GCSsweeptobefnz: { 1166 case GCSsweeptobefnz: {
1166 return sweepstep(L, g, GCSsweepmainth, NULL); 1167 return sweepstep(L, g, GCSsweepthreads, &g->mainthread->next);
1168 }
1169 case GCSsweepthreads: {
1170 return sweepstep(L, g, GCSsweepend, NULL);
1167 } 1171 }
1168 case GCSsweepmainth: { /* sweep main thread */ 1172 case GCSsweepend: {
1169 GCObject *mt = obj2gco(g->mainthread); 1173 makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */
1170 sweeplist(L, &mt, 1);
1171 checkBuffer(L); 1174 checkBuffer(L);
1172 g->gcstate = GCSpause; /* finish collection */ 1175 g->gcstate = GCSpause; /* finish collection */
1173 return GCSWEEPCOST; 1176 return GCSWEEPCOST;
diff --git a/lgc.h b/lgc.h
index f52c9ae7..7a449829 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.72 2013/09/11 12:26:14 roberto Exp roberto $ 2** $Id: lgc.h,v 2.73 2013/09/11 12:47:48 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*/
@@ -43,12 +43,13 @@
43#define GCSsweepfin 4 43#define GCSsweepfin 4
44#define GCSsweepall 5 44#define GCSsweepall 5
45#define GCSsweeptobefnz 6 45#define GCSsweeptobefnz 6
46#define GCSsweepmainth 7 46#define GCSsweepthreads 7
47#define GCSpause 8 47#define GCSsweepend 8
48#define GCSpause 9
48 49
49 50
50#define issweepphase(g) \ 51#define issweepphase(g) \
51 (GCSsweeplocal <= (g)->gcstate && (g)->gcstate <= GCSsweepmainth) 52 (GCSsweeplocal <= (g)->gcstate && (g)->gcstate <= GCSsweepend)
52 53
53 54
54/* 55/*
diff --git a/lstate.c b/lstate.c
index 414e27d2..f9d857fb 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.111 2013/09/05 19:31:49 roberto Exp roberto $ 2** $Id: lstate.c,v 2.112 2013/09/11 12:26:14 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*/
@@ -165,14 +165,6 @@ static void init_registry (lua_State *L, global_State *g) {
165 sethvalue(L, &g->l_registry, registry); 165 sethvalue(L, &g->l_registry, registry);
166 luaH_resize(L, registry, LUA_RIDX_LAST, 0); 166 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
167 nolocal(obj2gco(registry)); 167 nolocal(obj2gco(registry));
168 /* registry is the first "regular" object created by a state; move it
169 from 'localgc' to 'allgc' so that it act as a "sentinel" there */
170 lua_assert(g->allgc == NULL &&
171 registry->next == NULL &&
172 g->localgc == obj2gco(registry));
173 g->allgc = g->localgc;
174 g->localgc = NULL;
175 l_setbit(registry->marked, LOCALMARK); /* mark that it is not in 'localgc' */
176 /* registry[LUA_RIDX_MAINTHREAD] = L */ 168 /* registry[LUA_RIDX_MAINTHREAD] = L */
177 setthvalue(L, &temp, L); /* temp = L */ 169 setthvalue(L, &temp, L); /* temp = L */
178 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); 170 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
@@ -243,11 +235,11 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
243 luaC_checkGC(L); 235 luaC_checkGC(L);
244 /* create new thread */ 236 /* create new thread */
245 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l; 237 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
246 L1->marked = luaC_white(g) | bitmask(LOCALMARK) | bitmask(NOLOCALBIT); 238 L1->marked = luaC_white(g) | bit2mask(NOLOCALBIT, LOCALMARK);
247 L1->tt = LUA_TTHREAD; 239 L1->tt = LUA_TTHREAD;
248 /* link it after 'l_registry' */ 240 /* link it on list of threads */
249 L1->next = hvalue(&g->l_registry)->next; 241 L1->next = g->mainthread->next;
250 hvalue(&g->l_registry)->next = obj2gco(L1); 242 g->mainthread->next = obj2gco(L1);
251 setthvalue(L, L->top, L1); 243 setthvalue(L, L->top, L1);
252 api_incr_top(L); 244 api_incr_top(L);
253 preinit_state(L1, g); 245 preinit_state(L1, g);
@@ -283,7 +275,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
283 L->next = NULL; 275 L->next = NULL;
284 L->tt = LUA_TTHREAD; 276 L->tt = LUA_TTHREAD;
285 g->currentwhite = bitmask(WHITE0BIT); 277 g->currentwhite = bitmask(WHITE0BIT);
286 L->marked = luaC_white(g) | bitmask(NOLOCALBIT); 278 L->marked = luaC_white(g) | bit2mask(NOLOCALBIT, LOCALMARK);
287 g->gckind = KGC_NORMAL; 279 g->gckind = KGC_NORMAL;
288 preinit_state(L, g); 280 preinit_state(L, g);
289 g->frealloc = f; 281 g->frealloc = f;
diff --git a/lstate.h b/lstate.h
index 40a23643..fc8f775d 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.93 2013/09/03 15:37:10 roberto Exp roberto $ 2** $Id: lstate.h,v 2.94 2013/09/05 19:31:49 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*/
@@ -16,20 +16,19 @@
16 16
17/* 17/*
18 18
19** Some notes about garbage-collected objects: All objects in Lua must 19** Some notes about garbage-collected objects: All objects in Lua must
20** be kept somehow accessible until being freed. 20** be kept somehow accessible until being freed, so all objects always
21** belong to one (and only one) of these lists, using field 'next' of
22** the 'CommonHeader' for the link:
21** 23**
22** Lua keeps most objects linked in list g->allgc. The link uses field 24** mainthread->next: all threads;
23** 'next' of the CommonHeader. Threads (except the main one) ar kept 25** localgc: all local objects not marked for finalization;
24** at the end of the 'allgc' list, after the 'l_registry' (which is 26** localfin: all local objects marked for finalization;
25** the first object to be added to the list). 27** allgc: all non local objects not marked for finalization;
26** 28** finobj: all non local objects marked for finalization;
27** List 'fixedgc' keep objects that are not to be collected (currently 29** tobefnz: all objects ready to be finalized;
30** fixedgc: all objects that are not to be collected (currently
28** only small strings, such as reserved words). 31** only small strings, such as reserved words).
29**
30** Live objects with finalizers are kept in the list g->finobj. The
31** list g->tobefnz links all objects being finalized. In particular, an
32** object has its FINALIZEDBIT set iff it is in one of these lists.
33 32
34*/ 33*/
35 34
diff --git a/ltests.c b/ltests.c
index 1db957cc..0f6a23dd 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.156 2013/09/11 12:26:14 roberto Exp roberto $ 2** $Id: ltests.c,v 2.157 2013/09/11 12:47:48 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*/
@@ -423,7 +423,6 @@ int lua_checkmemory (lua_State *L) {
423 global_State *g = G(L); 423 global_State *g = G(L);
424 GCObject *o; 424 GCObject *o;
425 int maybedead; 425 int maybedead;
426 int isthread;
427 if (keepinvariant(g)) { 426 if (keepinvariant(g)) {
428 lua_assert(!iswhite(obj2gco(g->mainthread))); 427 lua_assert(!iswhite(obj2gco(g->mainthread)));
429 lua_assert(!iswhite(gcvalue(&g->l_registry))); 428 lua_assert(!iswhite(gcvalue(&g->l_registry)));
@@ -443,14 +442,20 @@ int lua_checkmemory (lua_State *L) {
443 /* check 'allgc' list */ 442 /* check 'allgc' list */
444 checkgray(g, g->allgc); 443 checkgray(g, g->allgc);
445 maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSsweepall); 444 maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSsweepall);
446 isthread = 0; /* not traversing threads (yet) */
447 for (o = g->allgc; o != NULL; o = gch(o)->next) { 445 for (o = g->allgc; o != NULL; o = gch(o)->next) {
448 if (gch(o)->tt == LUA_TTHREAD) isthread = 1; /* now travesing threads... */
449 else lua_assert(!isthread); /* ... and only threads */
450 checkobject(g, o, maybedead); 446 checkobject(g, o, maybedead);
451 lua_assert(!tofinalize(o) && testbit(o->gch.marked, LOCALMARK)); 447 lua_assert(!tofinalize(o) && testbit(o->gch.marked, LOCALMARK));
452 lua_assert(testbit(o->gch.marked, NOLOCALBIT)); 448 lua_assert(testbit(o->gch.marked, NOLOCALBIT));
453 } 449 }
450 /* check thread list */
451 checkgray(g, obj2gco(g->mainthread));
452 maybedead = (GCSatomic < g->gcstate && g->gcstate <= GCSsweepthreads);
453 for (o = obj2gco(g->mainthread); o != NULL; o = gch(o)->next) {
454 checkobject(g, o, maybedead);
455 lua_assert(!tofinalize(o) && testbit(o->gch.marked, LOCALMARK));
456 lua_assert(testbit(o->gch.marked, NOLOCALBIT));
457 lua_assert(gch(o)->tt == LUA_TTHREAD);
458 }
454 /* check 'localfin' list */ 459 /* check 'localfin' list */
455 checkgray(g, g->localfin); 460 checkgray(g, g->localfin);
456 for (o = g->localfin; o != NULL; o = gch(o)->next) { 461 for (o = g->localfin; o != NULL; o = gch(o)->next) {
@@ -650,8 +655,8 @@ static int gc_local (lua_State *L) {
650 655
651static int gc_state (lua_State *L) { 656static int gc_state (lua_State *L) {
652 static const char *statenames[] = {"propagate", "atomic", 657 static const char *statenames[] = {"propagate", "atomic",
653 "sweeplocal", "sweeplocfin", "sweepfin", "sweepall", "sweeptobefnz", 658 "sweeplocal", "sweeplocfin", "sweepfin", "sweepall",
654 "sweepmainth", "pause", ""}; 659 "sweeptobefnz", "sweepthreads", "sweepend", "pause", ""};
655 int option = luaL_checkoption(L, 1, "", statenames); 660 int option = luaL_checkoption(L, 1, "", statenames);
656 if (option == GCSpause + 1) { 661 if (option == GCSpause + 1) {
657 lua_pushstring(L, statenames[G(L)->gcstate]); 662 lua_pushstring(L, statenames[G(L)->gcstate]);