aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/lgc.c b/lgc.c
index 72984d2a..87ec40c9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.156 2002/11/11 11:52:43 roberto Exp roberto $ 2** $Id: lgc.c,v 1.157 2002/11/13 11:49:19 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,6 +47,13 @@ typedef struct GCState {
47#define markfinalized(u) resetbit((u)->uv.marked, 1) 47#define markfinalized(u) resetbit((u)->uv.marked, 1)
48 48
49 49
50#define KEYWEAKBIT 1
51#define VALUEWEAKBIT 2
52#define KEYWEAK (1<<KEYWEAKBIT)
53#define VALUEWEAK (1<<VALUEWEAKBIT)
54
55
56
50#define markobject(st,o) { checkconsistency(o); \ 57#define markobject(st,o) { checkconsistency(o); \
51 if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); } 58 if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
52 59
@@ -140,17 +147,23 @@ static void traversetable (GCState *st, Table *h) {
140 int i; 147 int i;
141 int weakkey = 0; 148 int weakkey = 0;
142 int weakvalue = 0; 149 int weakvalue = 0;
150 const TObject *mode;
143 markvalue(st, h->metatable); 151 markvalue(st, h->metatable);
144 lua_assert(h->lsizenode || h->node == st->G->dummynode); 152 lua_assert(h->lsizenode || h->node == st->G->dummynode);
145 if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ 153 mode = gfasttm(st->G, h->metatable, TM_MODE);
146 GCObject **weaklist; 154 if (mode && ttisstring(mode)) { /* is there a weak mode? */
147 weakkey = h->mode & WEAKKEY; 155 weakkey = (strchr(svalue(mode), 'k') != NULL);
148 weakvalue = h->mode & WEAKVALUE; 156 weakvalue = (strchr(svalue(mode), 'v') != NULL);
149 weaklist = (weakkey && weakvalue) ? &st->wkv : 157 if (weakkey || weakvalue) { /* is really weak? */
150 (weakkey) ? &st->wk : 158 GCObject **weaklist;
151 &st->wv; 159 h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
152 h->gclist = *weaklist; /* must be cleared after GC, ... */ 160 h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
153 *weaklist = valtogco(h); /* ... so put in the appropriate list */ 161 weaklist = (weakkey && weakvalue) ? &st->wkv :
162 (weakkey) ? &st->wk :
163 &st->wv;
164 h->gclist = *weaklist; /* must be cleared after GC, ... */
165 *weaklist = valtogco(h); /* ... so put in the appropriate list */
166 }
154 } 167 }
155 if (!weakvalue) { 168 if (!weakvalue) {
156 i = sizearray(h); 169 i = sizearray(h);
@@ -280,7 +293,7 @@ static void cleartablekeys (GCObject *l) {
280 while (l) { 293 while (l) {
281 Table *h = gcotoh(l); 294 Table *h = gcotoh(l);
282 int i = sizenode(h); 295 int i = sizenode(h);
283 lua_assert(h->mode & WEAKKEY); 296 lua_assert(h->marked & KEYWEAK);
284 while (i--) { 297 while (i--) {
285 Node *n = node(h, i); 298 Node *n = node(h, i);
286 if (!valismarked(key(n))) /* key was collected? */ 299 if (!valismarked(key(n))) /* key was collected? */
@@ -298,7 +311,7 @@ static void cleartablevalues (GCObject *l) {
298 while (l) { 311 while (l) {
299 Table *h = gcotoh(l); 312 Table *h = gcotoh(l);
300 int i = sizearray(h); 313 int i = sizearray(h);
301 lua_assert(h->mode & WEAKVALUE); 314 lua_assert(h->marked & VALUEWEAK);
302 while (i--) { 315 while (i--) {
303 TObject *o = &h->array[i]; 316 TObject *o = &h->array[i];
304 if (!valismarked(o)) /* value was collected? */ 317 if (!valismarked(o)) /* value was collected? */