aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-09 19:50:35 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-01-09 19:50:35 -0200
commitb3bb0f132b2a3dba88385f8d71ba3f34252d94e4 (patch)
tree111d09e92f36a4525ee9a62596925ac6cc9567b0 /lgc.c
parentfacfec0687ff20351d3c7520344a722b9149c9ea (diff)
downloadlua-b3bb0f132b2a3dba88385f8d71ba3f34252d94e4.tar.gz
lua-b3bb0f132b2a3dba88385f8d71ba3f34252d94e4.tar.bz2
lua-b3bb0f132b2a3dba88385f8d71ba3f34252d94e4.zip
new interface for weak modes
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c46
1 files changed, 28 insertions, 18 deletions
diff --git a/lgc.c b/lgc.c
index d7971346..64eee046 100644
--- a/lgc.c
+++ b/lgc.c
@@ -4,6 +4,8 @@
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
6 6
7#include <string.h>
8
7#include "lua.h" 9#include "lua.h"
8 10
9#include "ldebug.h" 11#include "ldebug.h"
@@ -22,6 +24,7 @@
22typedef struct GCState { 24typedef struct GCState {
23 Table *tmark; /* list of marked tables to be visited */ 25 Table *tmark; /* list of marked tables to be visited */
24 Table *toclear; /* list of visited weak tables (to be cleared after GC) */ 26 Table *toclear; /* list of visited weak tables (to be cleared after GC) */
27 lua_State *L;
25} GCState; 28} GCState;
26 29
27 30
@@ -119,8 +122,8 @@ static void markobject (GCState *st, TObject *o) {
119} 122}
120 123
121 124
122static void markstacks (lua_State *L, GCState *st) { 125static void markstacks (GCState *st) {
123 lua_State *L1 = L; 126 lua_State *L1 = st->L;
124 do { /* for each thread */ 127 do { /* for each thread */
125 StkId o, lim; 128 StkId o, lim;
126 for (o=L1->stack; o<L1->top; o++) 129 for (o=L1->stack; o<L1->top; o++)
@@ -130,15 +133,15 @@ static void markstacks (lua_State *L, GCState *st) {
130 for (; o<=lim; o++) setnilvalue(o); 133 for (; o<=lim; o++) setnilvalue(o);
131 lua_assert(L1->previous->next == L1 && L1->next->previous == L1); 134 lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
132 L1 = L1->next; 135 L1 = L1->next;
133 } while (L1 != L); 136 } while (L1 != st->L);
134} 137}
135 138
136 139
137static void markudet (lua_State *L, GCState *st) { 140static void markudet (GCState *st) {
138 Udata *u; 141 Udata *u;
139 for (u = G(L)->rootudata; u; u = u->uv.next) 142 for (u = G(st->L)->rootudata; u; u = u->uv.next)
140 marktable(st, u->uv.eventtable); 143 marktable(st, u->uv.eventtable);
141 for (u = G(L)->tmudata; u; u = u->uv.next) 144 for (u = G(st->L)->tmudata; u; u = u->uv.next)
142 marktable(st, u->uv.eventtable); 145 marktable(st, u->uv.eventtable);
143} 146}
144 147
@@ -152,13 +155,20 @@ static void removekey (Node *n) {
152 155
153static void traversetable (GCState *st, Table *h) { 156static void traversetable (GCState *st, Table *h) {
154 int i; 157 int i;
155 int mode = h->weakmode; 158 const TObject *mode;
159 int weakkey = 0;
160 int weakvalue = 0;
161 marktable(st, h->eventtable);
162 mode = fasttm(st->L, h->eventtable, TM_WEAKMODE);
156 if (mode) { /* weak table? must be cleared after GC... */ 163 if (mode) { /* weak table? must be cleared after GC... */
157 h->mark = st->toclear; /* put in the appropriate list */ 164 h->mark = st->toclear; /* put in the appropriate list */
158 st->toclear = h; 165 st->toclear = h;
166 if (ttype(mode) == LUA_TSTRING) {
167 weakkey = (strchr(svalue(mode), 'k') != NULL);
168 weakvalue = (strchr(svalue(mode), 'v') != NULL);
169 }
159 } 170 }
160 marktable(st, h->eventtable); 171 if (!weakvalue) {
161 if (!(mode & LUA_WEAK_VALUE)) {
162 i = sizearray(h); 172 i = sizearray(h);
163 while (i--) 173 while (i--)
164 markobject(st, &h->array[i]); 174 markobject(st, &h->array[i]);
@@ -168,18 +178,18 @@ static void traversetable (GCState *st, Table *h) {
168 Node *n = node(h, i); 178 Node *n = node(h, i);
169 if (ttype(val(n)) != LUA_TNIL) { 179 if (ttype(val(n)) != LUA_TNIL) {
170 lua_assert(ttype(key(n)) != LUA_TNIL); 180 lua_assert(ttype(key(n)) != LUA_TNIL);
171 if (!(mode & LUA_WEAK_KEY)) 181 if (!weakkey) markobject(st, key(n));
172 markobject(st, key(n)); 182 if (!weakvalue) markobject(st, val(n));
173 if (!(mode & LUA_WEAK_VALUE))
174 markobject(st, val(n));
175 } 183 }
176 } 184 }
177} 185}
178 186
179 187
180static void markall (lua_State *L, GCState *st) { 188static void markall (GCState *st) {
181 markstacks(L, st); /* mark all stacks */ 189 lua_assert(hvalue(defaultet(st->L))->flags == cast(unsigned short, ~0));
182 markudet(L, st); /* mark userdata's event tables */ 190 /* table is unchanged */
191 markstacks(st); /* mark all stacks */
192 markudet(st); /* mark userdata's event tables */
183 while (st->tmark) { /* traverse marked tables */ 193 while (st->tmark) { /* traverse marked tables */
184 Table *h = st->tmark; /* get first table from list */ 194 Table *h = st->tmark; /* get first table from list */
185 st->tmark = h->mark; /* remove it from list */ 195 st->tmark = h->mark; /* remove it from list */
@@ -210,7 +220,6 @@ static int hasmark (const TObject *o) {
210static void cleartables (Table *h) { 220static void cleartables (Table *h) {
211 for (; h; h = h->mark) { 221 for (; h; h = h->mark) {
212 int i; 222 int i;
213 lua_assert(h->weakmode);
214 i = sizearray(h); 223 i = sizearray(h);
215 while (i--) { 224 while (i--) {
216 TObject *o = &h->array[i]; 225 TObject *o = &h->array[i];
@@ -421,9 +430,10 @@ void luaC_collect (lua_State *L, int all) {
421 430
422void luaC_collectgarbage (lua_State *L) { 431void luaC_collectgarbage (lua_State *L) {
423 GCState st; 432 GCState st;
433 st.L = L;
424 st.tmark = NULL; 434 st.tmark = NULL;
425 st.toclear = NULL; 435 st.toclear = NULL;
426 markall(L, &st); 436 markall(&st);
427 cleartables(st.toclear); 437 cleartables(st.toclear);
428 luaC_collect(L, 0); 438 luaC_collect(L, 0);
429 checkMbuffer(L); 439 checkMbuffer(L);