diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-06-06 15:00:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-06-06 15:00:19 -0300 |
commit | d5b83ead90fba27faa344c72406d85987d2460a4 (patch) | |
tree | 96d73c1b872b6b01a28c0586b871d37185034ba9 /lgc.c | |
parent | da673d31aaa05e8dff60c0b601b9f15c4f9182a8 (diff) | |
download | lua-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.c | 62 |
1 files changed, 29 insertions, 33 deletions
@@ -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 | ||
83 | static void markobject (GCState *st, TObject *o) { | 83 | static 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 | ||
191 | static int hasmark (const TObject *o) { | 194 | static 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 | ||
278 | static void checktab (lua_State *L, stringtable *tb) { | 283 | static 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 | ||
306 | static 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 |
331 | static void checkMbuffer (lua_State *L) { | 327 | static 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 | ||
371 | void luaC_collect (lua_State *L, int all) { | 367 | void 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); |