aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-06-06 15:00:19 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-06-06 15:00:19 -0300
commitd5b83ead90fba27faa344c72406d85987d2460a4 (patch)
tree96d73c1b872b6b01a28c0586b871d37185034ba9 /lgc.c
parentda673d31aaa05e8dff60c0b601b9f15c4f9182a8 (diff)
downloadlua-d5b83ead90fba27faa344c72406d85987d2460a4.tar.gz
lua-d5b83ead90fba27faa344c72406d85987d2460a4.tar.bz2
lua-d5b83ead90fba27faa344c72406d85987d2460a4.zip
new implementation for userdatas, without `keys'
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c62
1 files changed, 29 insertions, 33 deletions
diff --git a/lgc.c b/lgc.c
index a82039dd..86b7d092 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.98 2001/06/05 18:17:01 roberto Exp roberto $ 2** $Id: lgc.c,v 1.99 2001/06/05 19:27:32 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*/
@@ -82,9 +82,12 @@ static void marktable (GCState *st, Hash *h) {
82 82
83static void markobject (GCState *st, TObject *o) { 83static void markobject (GCState *st, TObject *o) {
84 switch (ttype(o)) { 84 switch (ttype(o)) {
85 case LUA_TUSERDATA: case LUA_TSTRING: 85 case LUA_TSTRING:
86 strmark(tsvalue(o)); 86 strmark(tsvalue(o));
87 break; 87 break;
88 case LUA_TUSERDATA:
89 uvalue(o)->marked = 1;
90 break;
88 case LUA_TFUNCTION: 91 case LUA_TFUNCTION:
89 markclosure(st, clvalue(o)); 92 markclosure(st, clvalue(o));
90 break; 93 break;
@@ -190,8 +193,10 @@ static void markall (lua_State *L) {
190 193
191static int hasmark (const TObject *o) { 194static int hasmark (const TObject *o) {
192 switch (ttype(o)) { 195 switch (ttype(o)) {
193 case LUA_TSTRING: case LUA_TUSERDATA: 196 case LUA_TSTRING:
194 return tsvalue(o)->marked; 197 return tsvalue(o)->marked;
198 case LUA_TUSERDATA:
199 return uvalue(o)->marked;
195 case LUA_TTABLE: 200 case LUA_TTABLE:
196 return ismarked(hvalue(o)); 201 return ismarked(hvalue(o));
197 case LUA_TFUNCTION: 202 case LUA_TFUNCTION:
@@ -275,9 +280,21 @@ static void collecttable (lua_State *L) {
275} 280}
276 281
277 282
278static void checktab (lua_State *L, stringtable *tb) { 283static void collectudata (lua_State *L) {
279 if (tb->nuse < (ls_nstr)(tb->size/4) && tb->size > MINPOWER2) 284 Udata **p = &G(L)->rootudata;
280 luaS_resize(L, tb, tb->size/2); /* table is too big */ 285 Udata *next;
286 while ((next = *p) != NULL) {
287 if (next->marked) {
288 next->marked = 0; /* unmark */
289 p = &next->next;
290 }
291 else { /* collect */
292 int tag = next->tag;
293 *p = next->next;
294 next->next = G(L)->TMtable[tag].collected; /* chain udata */
295 G(L)->TMtable[tag].collected = next;
296 }
297 }
281} 298}
282 299
283 300
@@ -299,33 +316,12 @@ static void collectstrings (lua_State *L, int all) {
299 } 316 }
300 } 317 }
301 } 318 }
302 checktab(L, &G(L)->strt); 319 if (G(L)->strt.nuse < (ls_nstr)(G(L)->strt.size/4) &&
320 G(L)->strt.size > MINPOWER2)
321 luaS_resize(L, G(L)->strt.size/2); /* table is too big */
303} 322}
304 323
305 324
306static void collectudata (lua_State *L, int all) {
307 int i;
308 for (i=0; i<G(L)->udt.size; i++) { /* for each list */
309 TString **p = &G(L)->udt.hash[i];
310 TString *next;
311 while ((next = *p) != NULL) {
312 lua_assert(next->marked <= 1);
313 if (next->marked && !all) { /* preserve? */
314 next->marked = 0;
315 p = &next->nexthash;
316 }
317 else { /* collect */
318 int tag = next->u.d.tag;
319 *p = next->nexthash;
320 next->nexthash = G(L)->TMtable[tag].collected; /* chain udata */
321 G(L)->TMtable[tag].collected = next;
322 G(L)->udt.nuse--;
323 }
324 }
325 }
326 checktab(L, &G(L)->udt);
327}
328
329 325
330#define MINBUFFER 256 326#define MINBUFFER 256
331static void checkMbuffer (lua_State *L) { 327static void checkMbuffer (lua_State *L) {
@@ -356,10 +352,10 @@ static void callgcTMudata (lua_State *L) {
356 int tag; 352 int tag;
357 G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */ 353 G(L)->GCthreshold = 2*G(L)->nblocks; /* avoid GC during tag methods */
358 for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ 354 for (tag=G(L)->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */
359 TString *udata; 355 Udata *udata;
360 while ((udata = G(L)->TMtable[tag].collected) != NULL) { 356 while ((udata = G(L)->TMtable[tag].collected) != NULL) {
361 TObject obj; 357 TObject obj;
362 G(L)->TMtable[tag].collected = udata->nexthash; /* remove it from list */ 358 G(L)->TMtable[tag].collected = udata->next; /* remove it from list */
363 setuvalue(&obj, udata); 359 setuvalue(&obj, udata);
364 callgcTM(L, &obj); 360 callgcTM(L, &obj);
365 luaM_free(L, udata, sizeudata(udata->len)); 361 luaM_free(L, udata, sizeudata(udata->len));
@@ -370,7 +366,7 @@ static void callgcTMudata (lua_State *L) {
370 366
371void luaC_collect (lua_State *L, int all) { 367void luaC_collect (lua_State *L, int all) {
372 lua_lockgc(L); 368 lua_lockgc(L);
373 collectudata(L, all); 369 collectudata(L);
374 callgcTMudata(L); 370 callgcTMudata(L);
375 collectstrings(L, all); 371 collectstrings(L, all);
376 collecttable(L); 372 collecttable(L);