aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-02-10 11:25:02 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-02-10 11:25:02 -0200
commit4df8800a01c7e44800ce59339c66b9257cd75c2a (patch)
tree226ae5cfc06164f6f01e33d778336c1ffd561d72
parent0e60572606684458b18febfcef0bc68235b461f4 (diff)
downloadlua-4df8800a01c7e44800ce59339c66b9257cd75c2a.tar.gz
lua-4df8800a01c7e44800ce59339c66b9257cd75c2a.tar.bz2
lua-4df8800a01c7e44800ce59339c66b9257cd75c2a.zip
cleaner way to free all objects
-rw-r--r--lfunc.c6
-rw-r--r--lgc.c54
-rw-r--r--lgc.h14
-rw-r--r--lstate.c9
4 files changed, 40 insertions, 43 deletions
diff --git a/lfunc.c b/lfunc.c
index 65d70cfb..d69f75dd 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $ 2** $Id: lfunc.c,v 2.7 2005/01/19 15:54:26 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*/
@@ -57,7 +57,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
57 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { 57 while ((p = ngcotouv(*pp)) != NULL && p->v >= level) {
58 lua_assert(p->v != &p->u.value); 58 lua_assert(p->v != &p->u.value);
59 if (p->v == level) { /* found a corresponding upvalue? */ 59 if (p->v == level) { /* found a corresponding upvalue? */
60 if (isdead(G(L), obj2gco(p))) /* is it dead? */ 60 if (isdead(g, obj2gco(p))) /* is it dead? */
61 changewhite(obj2gco(p)); /* ressurect it */ 61 changewhite(obj2gco(p)); /* ressurect it */
62 return p; 62 return p;
63 } 63 }
@@ -106,7 +106,7 @@ void luaF_close (lua_State *L, StkId level) {
106 setobj(L, &uv->u.value, uv->v); 106 setobj(L, &uv->u.value, uv->v);
107 if (isgray(o)) { 107 if (isgray(o)) {
108 gray2black(o); /* closed upvalues are never gray */ 108 gray2black(o); /* closed upvalues are never gray */
109 luaC_barrier(L, uv, uv->v); 109 luaC_barrier(L, uv, &uv->u.value);
110 } 110 }
111 uv->v = &uv->u.value; /* now current value lives here */ 111 uv->v = &uv->u.value; /* now current value lives here */
112 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ 112 luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
diff --git a/lgc.c b/lgc.c
index d40b174c..27198217 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $ 2** $Id: lgc.c,v 2.22 2005/01/18 17:18:09 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*/
@@ -29,13 +29,11 @@
29#define GCFINALIZECOST 100 29#define GCFINALIZECOST 100
30 30
31 31
32#define FIXEDMASK bitmask(FIXEDBIT)
33
34#define maskmarks \ 32#define maskmarks \
35 cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT))) 33 cast(lu_byte, ~(bitmask(BLACKBIT)|WHITEBITS))
36 34
37#define makewhite(g,x) \ 35#define makewhite(g,x) \
38 ((x)->gch.marked = ((x)->gch.marked & maskmarks) | g->currentwhite) 36 ((x)->gch.marked = ((x)->gch.marked & maskmarks) | luaC_white(g))
39 37
40#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 38#define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
41#define gray2black(x) setbit((x)->gch.marked, BLACKBIT) 39#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
@@ -60,6 +58,8 @@
60 reallymarkobject(g, obj2gco(t)); } 58 reallymarkobject(g, obj2gco(t)); }
61 59
62 60
61#define setthreshold(g) (g->GCthreshold = (g->estimate/100) * g->gcpace)
62
63 63
64static void removeentry (Node *n) { 64static void removeentry (Node *n) {
65 lua_assert(ttisnil(gval(n))); 65 lua_assert(ttisnil(gval(n)));
@@ -400,24 +400,23 @@ static void freeobj (lua_State *L, GCObject *o) {
400 400
401 401
402 402
403#define sweepwholelist(L,p) sweeplist(L,p,LUA_MAXINT32) 403#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)
404 404
405 405
406static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) { 406static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
407 GCObject *curr; 407 GCObject *curr;
408 global_State *g = G(L); 408 global_State *g = G(L);
409 int whitebit = otherwhite(g); 409 int deadmask = otherwhite(g);
410 int deadmask = whitebit | FIXEDMASK;
411 while ((curr = *p) != NULL && count-- > 0) { 410 while ((curr = *p) != NULL && count-- > 0) {
412 if ((curr->gch.marked ^ whitebit) & deadmask) { 411 if (curr->gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
412 sweepwholelist(L, &gco2th(curr)->openupval);
413 if ((curr->gch.marked ^ WHITEBITS) & deadmask) { /* not dead? */
413 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT)); 414 lua_assert(!isdead(g, curr) || testbit(curr->gch.marked, FIXEDBIT));
414 makewhite(g, curr); 415 makewhite(g, curr); /* make it white (for next cycle) */
415 if (curr->gch.tt == LUA_TTHREAD)
416 sweepwholelist(L, &gco2th(curr)->openupval);
417 p = &curr->gch.next; 416 p = &curr->gch.next;
418 } 417 }
419 else { 418 else { /* must erase `curr' */
420 lua_assert(isdead(g, curr)); 419 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
421 *p = curr->gch.next; 420 *p = curr->gch.next;
422 if (curr == g->rootgc) /* is the first element of the list? */ 421 if (curr == g->rootgc) /* is the first element of the list? */
423 g->rootgc = curr->gch.next; /* adjust first */ 422 g->rootgc = curr->gch.next; /* adjust first */
@@ -428,21 +427,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_int32 count) {
428} 427}
429 428
430 429
431
432static void freelist (lua_State *L, GCObject **p) {
433 while (*p) {
434 GCObject *curr = *p;
435 *p = (*p)->gch.next;
436 if (curr != obj2gco(L))
437 freeobj(L, curr);
438 }
439}
440
441
442static void checkSizes (lua_State *L) { 430static void checkSizes (lua_State *L) {
443 global_State *g = G(L); 431 global_State *g = G(L);
444 /* check size of string hash */ 432 /* check size of string hash */
445 if (g->strt.nuse < cast(lu_int32, G(L)->strt.size/4) && 433 if (g->strt.nuse < cast(lu_int32, g->strt.size/4) &&
446 g->strt.size > MINSTRTABSIZE*2) 434 g->strt.size > MINSTRTABSIZE*2)
447 luaS_resize(L, g->strt.size/2); /* table is too big */ 435 luaS_resize(L, g->strt.size/2); /* table is too big */
448 /* check size of buffer */ 436 /* check size of buffer */
@@ -487,9 +475,10 @@ void luaC_callGCTM (lua_State *L) {
487void luaC_freeall (lua_State *L) { 475void luaC_freeall (lua_State *L) {
488 global_State *g = G(L); 476 global_State *g = G(L);
489 int i; 477 int i;
490 freelist(L, &g->rootgc); 478 g->currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
479 sweepwholelist(L, &g->rootgc);
491 for (i = 0; i < g->strt.size; i++) /* free all string lists */ 480 for (i = 0; i < g->strt.size; i++) /* free all string lists */
492 freelist(L, &G(L)->strt.hash[i]); 481 sweepwholelist(L, &g->strt.hash[i]);
493} 482}
494 483
495 484
@@ -604,6 +593,8 @@ static l_mem singlestep (lua_State *L) {
604void luaC_step (lua_State *L) { 593void luaC_step (lua_State *L) {
605 global_State *g = G(L); 594 global_State *g = G(L);
606 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul; 595 l_mem lim = (GCSTEPSIZE/100) * g->gcstepmul;
596 if (lim == 0)
597 lim = (MAX_LUMEM-1)/2; /* no limit */
607 g->gcdept += g->totalbytes - g->GCthreshold; 598 g->gcdept += g->totalbytes - g->GCthreshold;
608 do { 599 do {
609 lim -= singlestep(L); 600 lim -= singlestep(L);
@@ -620,7 +611,7 @@ void luaC_step (lua_State *L) {
620 } 611 }
621 else { 612 else {
622 lua_assert(g->totalbytes >= g->estimate); 613 lua_assert(g->totalbytes >= g->estimate);
623 g->GCthreshold = (g->estimate/100) * g->gcpace; 614 setthreshold(g);
624 } 615 }
625} 616}
626 617
@@ -637,6 +628,7 @@ void luaC_fullgc (lua_State *L) {
637 g->weak = NULL; 628 g->weak = NULL;
638 g->gcstate = GCSsweepstring; 629 g->gcstate = GCSsweepstring;
639 } 630 }
631 lua_assert(g->gcstate != GCSpause && g->gcstate != GCSpropagate);
640 /* finish any pending sweep phase */ 632 /* finish any pending sweep phase */
641 while (g->gcstate != GCSfinalize) { 633 while (g->gcstate != GCSfinalize) {
642 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep); 634 lua_assert(g->gcstate == GCSsweepstring || g->gcstate == GCSsweep);
@@ -646,7 +638,7 @@ void luaC_fullgc (lua_State *L) {
646 while (g->gcstate != GCSpause) { 638 while (g->gcstate != GCSpause) {
647 singlestep(L); 639 singlestep(L);
648 } 640 }
649 g->GCthreshold = 2*g->estimate; 641 setthreshold(g);
650} 642}
651 643
652 644
diff --git a/lgc.h b/lgc.h
index bec5a728..c3039ee4 100644
--- a/lgc.h
+++ b/lgc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.h,v 2.9 2004/09/15 20:38:15 roberto Exp $ 2** $Id: lgc.h,v 2.10 2005/01/19 15:54:26 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*/
@@ -47,8 +47,10 @@
47** bit 3 - for tables: has weak keys 47** bit 3 - for tables: has weak keys
48** bit 4 - for tables: has weak values 48** bit 4 - for tables: has weak values
49** bit 5 - object is fixed (should not be collected) 49** bit 5 - object is fixed (should not be collected)
50** bit 6 - object is "super" fixed (only the main thread)
50*/ 51*/
51 52
53
52#define WHITE0BIT 0 54#define WHITE0BIT 0
53#define WHITE1BIT 1 55#define WHITE1BIT 1
54#define BLACKBIT 2 56#define BLACKBIT 2
@@ -56,21 +58,23 @@
56#define KEYWEAKBIT 3 58#define KEYWEAKBIT 3
57#define VALUEWEAKBIT 4 59#define VALUEWEAKBIT 4
58#define FIXEDBIT 5 60#define FIXEDBIT 5
61#define SFIXEDBIT 6
62#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
59 63
60 64
61#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) 65#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
62#define isblack(x) testbit((x)->gch.marked, BLACKBIT) 66#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
63#define isgray(x) (!isblack(x) && !iswhite(x)) 67#define isgray(x) (!isblack(x) && !iswhite(x))
64 68
65#define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT)) 69#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
66#define isdead(g,v) ((v)->gch.marked & otherwhite(g)) 70#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)
67 71
68#define changewhite(x) ((x)->gch.marked ^= bit2mask(WHITE0BIT, WHITE1BIT)) 72#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
69#define gray2black(x) setbit((x)->gch.marked, BLACKBIT) 73#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
70 74
71#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) 75#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
72 76
73#define luaC_white(g) cast(lu_byte, (g)->currentwhite) 77#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
74 78
75 79
76#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \ 80#define luaC_checkGC(L) { if (G(L)->totalbytes >= G(L)->GCthreshold) \
diff --git a/lstate.c b/lstate.c
index 7596a55d..48d383f1 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.22 2005/01/14 14:19:42 roberto Exp $ 2** $Id: lstate.c,v 2.23 2005/01/18 17:18:09 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*/
@@ -114,7 +114,7 @@ static void close_state (lua_State *L) {
114 global_State *g = G(L); 114 global_State *g = G(L);
115 luaF_close(L, L->stack); /* close all upvalues for this thread */ 115 luaF_close(L, L->stack); /* close all upvalues for this thread */
116 luaC_freeall(L); /* collect all objects */ 116 luaC_freeall(L); /* collect all objects */
117 lua_assert(g->rootgc == NULL); 117 lua_assert(g->rootgc == obj2gco(L));
118 lua_assert(g->strt.nuse == 0); 118 lua_assert(g->strt.nuse == 0);
119 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 119 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
120 luaZ_freebuffer(L, &g->buff); 120 luaZ_freebuffer(L, &g->buff);
@@ -156,8 +156,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
156 g = &((LG *)L)->g; 156 g = &((LG *)L)->g;
157 L->next = NULL; 157 L->next = NULL;
158 L->tt = LUA_TTHREAD; 158 L->tt = LUA_TTHREAD;
159 L->marked = g->currentwhite = bitmask(WHITE0BIT); 159 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
160 setbit(L->marked, FIXEDBIT); 160 L->marked = luaC_white(g);
161 set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
161 preinit_state(L, g); 162 preinit_state(L, g);
162 g->realloc = f; 163 g->realloc = f;
163 g->ud = ud; 164 g->ud = ud;