diff options
| -rw-r--r-- | lfunc.c | 4 | ||||
| -rw-r--r-- | lgc.c | 70 | ||||
| -rw-r--r-- | lgc.h | 31 | ||||
| -rw-r--r-- | lstring.c | 4 | ||||
| -rw-r--r-- | lstring.h | 6 |
5 files changed, 69 insertions, 46 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.68 2003/10/02 19:21:09 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.69 2003/10/20 17:42:41 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 | */ |
| @@ -64,7 +64,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
| 64 | } | 64 | } |
| 65 | v = luaM_new(L, UpVal); /* not found: create a new one */ | 65 | v = luaM_new(L, UpVal); /* not found: create a new one */ |
| 66 | v->tt = LUA_TUPVAL; | 66 | v->tt = LUA_TUPVAL; |
| 67 | v->marked = 1; /* open upvalues should not be collected */ | 67 | v->marked = bitmask(BLACKBIT); /* open upvalues should not be collected */ |
| 68 | v->v = level; /* current value lives in the stack */ | 68 | v->v = level; /* current value lives in the stack */ |
| 69 | v->next = *pp; /* chain it in the proper position */ | 69 | v->next = *pp; /* chain it in the proper position */ |
| 70 | *pp = valtogco(v); | 70 | *pp = valtogco(v); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.176 2003/07/29 19:25:37 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.177 2003/08/27 21:01:44 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,45 +29,38 @@ typedef struct GCState { | |||
| 29 | } GCState; | 29 | } GCState; |
| 30 | 30 | ||
| 31 | 31 | ||
| 32 | /* | ||
| 33 | ** some userful bit tricks | ||
| 34 | */ | ||
| 35 | #define setbit(x,b) ((x) |= (1<<(b))) | ||
| 36 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) | ||
| 37 | #define testbit(x,b) ((x) & (1<<(b))) | ||
| 38 | 32 | ||
| 39 | #define unmark(x) resetbit((x)->gch.marked, 0) | 33 | #define unblack(x) resetbit((x)->gch.marked, BLACKBIT) |
| 40 | #define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) | 34 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
| 35 | #define blacken(x) setbit((x)->gch.marked, BLACKBIT) | ||
| 41 | 36 | ||
| 42 | #define stringmark(s) setbit((s)->tsv.marked, 0) | 37 | #define stringmark(s) setbit((s)->tsv.marked, BLACKBIT) |
| 43 | 38 | ||
| 44 | 39 | ||
| 45 | #define isfinalized(u) (!testbit((u)->uv.marked, 1)) | 40 | #define isfinalized(u) testbit((u)->uv.marked, FINALIZEDBIT) |
| 46 | #define markfinalized(u) resetbit((u)->uv.marked, 1) | 41 | #define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) |
| 47 | 42 | ||
| 48 | 43 | ||
| 49 | #define KEYWEAKBIT 1 | 44 | #define KEYWEAK bitmask(KEYWEAKBIT) |
| 50 | #define VALUEWEAKBIT 2 | 45 | #define VALUEWEAK bitmask(VALUEWEAKBIT) |
| 51 | #define KEYWEAK (1<<KEYWEAKBIT) | ||
| 52 | #define VALUEWEAK (1<<VALUEWEAKBIT) | ||
| 53 | 46 | ||
| 54 | 47 | ||
| 55 | 48 | ||
| 56 | #define markobject(st,o) { checkconsistency(o); \ | 49 | #define markobject(st,o) { checkconsistency(o); \ |
| 57 | if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); } | 50 | if (iscollectable(o) && !isblack(gcvalue(o))) reallymarkobject(st,gcvalue(o)); } |
| 58 | 51 | ||
| 59 | #define condmarkobject(st,o,c) { checkconsistency(o); \ | 52 | #define condmarkobject(st,o,c) { checkconsistency(o); \ |
| 60 | if (iscollectable(o) && !ismarked(gcvalue(o)) && (c)) \ | 53 | if (iscollectable(o) && !isblack(gcvalue(o)) && (c)) \ |
| 61 | reallymarkobject(st,gcvalue(o)); } | 54 | reallymarkobject(st,gcvalue(o)); } |
| 62 | 55 | ||
| 63 | #define markvalue(st,t) { if (!ismarked(valtogco(t))) \ | 56 | #define markvalue(st,t) { if (!isblack(valtogco(t))) \ |
| 64 | reallymarkobject(st, valtogco(t)); } | 57 | reallymarkobject(st, valtogco(t)); } |
| 65 | 58 | ||
| 66 | 59 | ||
| 67 | 60 | ||
| 68 | static void reallymarkobject (GCState *st, GCObject *o) { | 61 | static void reallymarkobject (GCState *st, GCObject *o) { |
| 69 | lua_assert(!ismarked(o)); | 62 | lua_assert(!isblack(o)); |
| 70 | setbit(o->gch.marked, 0); /* mark object */ | 63 | blacken(o); |
| 71 | switch (o->gch.tt) { | 64 | switch (o->gch.tt) { |
| 72 | case LUA_TUSERDATA: { | 65 | case LUA_TUSERDATA: { |
| 73 | markvalue(st, gcotou(o)->uv.metatable); | 66 | markvalue(st, gcotou(o)->uv.metatable); |
| @@ -101,7 +94,7 @@ static void reallymarkobject (GCState *st, GCObject *o) { | |||
| 101 | static void marktmu (GCState *st) { | 94 | static void marktmu (GCState *st) { |
| 102 | GCObject *u; | 95 | GCObject *u; |
| 103 | for (u = st->g->tmudata; u; u = u->gch.next) { | 96 | for (u = st->g->tmudata; u; u = u->gch.next) { |
| 104 | unmark(u); /* may be marked, if left from previous GC */ | 97 | unblack(u); /* may be marked, if left from previous GC */ |
| 105 | reallymarkobject(st, u); | 98 | reallymarkobject(st, u); |
| 106 | } | 99 | } |
| 107 | } | 100 | } |
| @@ -116,7 +109,7 @@ size_t luaC_separateudata (lua_State *L) { | |||
| 116 | GCObject **lastcollected = &collected; | 109 | GCObject **lastcollected = &collected; |
| 117 | while ((curr = *p) != NULL) { | 110 | while ((curr = *p) != NULL) { |
| 118 | lua_assert(curr->gch.tt == LUA_TUSERDATA); | 111 | lua_assert(curr->gch.tt == LUA_TUSERDATA); |
| 119 | if (ismarked(curr) || isfinalized(gcotou(curr))) | 112 | if (isblack(curr) || isfinalized(gcotou(curr))) |
| 120 | p = &curr->gch.next; /* don't bother with them */ | 113 | p = &curr->gch.next; /* don't bother with them */ |
| 121 | 114 | ||
| 122 | else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { | 115 | else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { |
| @@ -216,9 +209,9 @@ static void traverseclosure (GCState *st, Closure *cl) { | |||
| 216 | markvalue(st, cl->l.p); | 209 | markvalue(st, cl->l.p); |
| 217 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ | 210 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ |
| 218 | UpVal *u = cl->l.upvals[i]; | 211 | UpVal *u = cl->l.upvals[i]; |
| 219 | if (!u->marked) { | 212 | if (!isblack(valtogco(u))) { |
| 213 | blacken(valtogco(u)); | ||
| 220 | markobject(st, &u->value); | 214 | markobject(st, &u->value); |
| 221 | u->marked = 1; | ||
| 222 | } | 215 | } |
| 223 | } | 216 | } |
| 224 | } | 217 | } |
| @@ -300,7 +293,7 @@ static int iscleared (const TObject *o, int iskey) { | |||
| 300 | stringmark(tsvalue(o)); /* strings are `values', so are never weak */ | 293 | stringmark(tsvalue(o)); /* strings are `values', so are never weak */ |
| 301 | return 0; | 294 | return 0; |
| 302 | } | 295 | } |
| 303 | return !ismarked(gcvalue(o)) || | 296 | return !isblack(gcvalue(o)) || |
| 304 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | 297 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); |
| 305 | } | 298 | } |
| 306 | 299 | ||
| @@ -319,8 +312,9 @@ static void cleartable (GCObject *l) { | |||
| 319 | while (l) { | 312 | while (l) { |
| 320 | Table *h = gcotoh(l); | 313 | Table *h = gcotoh(l); |
| 321 | int i = h->sizearray; | 314 | int i = h->sizearray; |
| 322 | lua_assert(h->marked & (KEYWEAK | VALUEWEAK)); | 315 | lua_assert(testbit(h->marked, VALUEWEAKBIT) || |
| 323 | if (h->marked & VALUEWEAK) { | 316 | testbit(h->marked, KEYWEAKBIT)); |
| 317 | if (testbit(h->marked, VALUEWEAKBIT)) { | ||
| 324 | while (i--) { | 318 | while (i--) { |
| 325 | TObject *o = &h->array[i]; | 319 | TObject *o = &h->array[i]; |
| 326 | if (iscleared(o, 0)) /* value was collected? */ | 320 | if (iscleared(o, 0)) /* value was collected? */ |
| @@ -363,12 +357,12 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 363 | } | 357 | } |
| 364 | 358 | ||
| 365 | 359 | ||
| 366 | static int sweeplist (lua_State *L, GCObject **p, int limit) { | 360 | static int sweeplist (lua_State *L, GCObject **p, int mask) { |
| 367 | GCObject *curr; | 361 | GCObject *curr; |
| 368 | int count = 0; /* number of collected items */ | 362 | int count = 0; /* number of collected items */ |
| 369 | while ((curr = *p) != NULL) { | 363 | while ((curr = *p) != NULL) { |
| 370 | if (curr->gch.marked > limit) { | 364 | if (curr->gch.marked & mask) { |
| 371 | unmark(curr); | 365 | unblack(curr); |
| 372 | p = &curr->gch.next; | 366 | p = &curr->gch.next; |
| 373 | } | 367 | } |
| 374 | else { | 368 | else { |
| @@ -381,10 +375,10 @@ static int sweeplist (lua_State *L, GCObject **p, int limit) { | |||
| 381 | } | 375 | } |
| 382 | 376 | ||
| 383 | 377 | ||
| 384 | static void sweepstrings (lua_State *L, int all) { | 378 | static void sweepstrings (lua_State *L, int mask) { |
| 385 | int i; | 379 | int i; |
| 386 | for (i=0; i<G(L)->strt.size; i++) { /* for each list */ | 380 | for (i=0; i<G(L)->strt.size; i++) { /* for each list */ |
| 387 | G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all); | 381 | G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], mask); |
| 388 | } | 382 | } |
| 389 | } | 383 | } |
| 390 | 384 | ||
| @@ -426,7 +420,7 @@ void luaC_callGCTM (lua_State *L) { | |||
| 426 | udata->uv.next = G(L)->rootudata; /* return it to `root' list */ | 420 | udata->uv.next = G(L)->rootudata; /* return it to `root' list */ |
| 427 | G(L)->rootudata = o; | 421 | G(L)->rootudata = o; |
| 428 | setuvalue(L->top - 1, udata); /* keep a reference to it */ | 422 | setuvalue(L->top - 1, udata); /* keep a reference to it */ |
| 429 | unmark(o); | 423 | unblack(o); |
| 430 | do1gcTM(L, udata); | 424 | do1gcTM(L, udata); |
| 431 | } | 425 | } |
| 432 | L->top--; | 426 | L->top--; |
| @@ -435,10 +429,10 @@ void luaC_callGCTM (lua_State *L) { | |||
| 435 | 429 | ||
| 436 | 430 | ||
| 437 | void luaC_sweep (lua_State *L, int all) { | 431 | void luaC_sweep (lua_State *L, int all) { |
| 438 | if (all) all = 256; /* larger than any mark */ | 432 | int mask = (all) ? 0 : (bitmask(BLACKBIT) | bitmask(FIXEDBIT)); |
| 439 | sweeplist(L, &G(L)->rootudata, all); | 433 | sweeplist(L, &G(L)->rootudata, mask); |
| 440 | sweepstrings(L, all); | 434 | sweepstrings(L, mask); |
| 441 | sweeplist(L, &G(L)->rootgc, all); | 435 | sweeplist(L, &G(L)->rootgc, mask); |
| 442 | } | 436 | } |
| 443 | 437 | ||
| 444 | 438 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 1.20 2003/07/16 20:49:02 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 1.21 2003/07/29 19:25:37 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 | */ |
| @@ -11,6 +11,35 @@ | |||
| 11 | #include "lobject.h" | 11 | #include "lobject.h" |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | /* | ||
| 15 | * ** some userful bit tricks | ||
| 16 | * */ | ||
| 17 | #define bitmask(b) (1<<(b)) | ||
| 18 | #define setbit(x,b) ((x) |= bitmask(b)) | ||
| 19 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~bitmask(b))) | ||
| 20 | #define testbit(x,b) ((x) & bitmask(b)) | ||
| 21 | |||
| 22 | |||
| 23 | |||
| 24 | /* | ||
| 25 | ** Layout for bit use in `marked' field: | ||
| 26 | ** bit 0 - object is white (not used yet) | ||
| 27 | ** bit 1 - object is black | ||
| 28 | ** bit 2 - For userdata: is finalized; | ||
| 29 | for tables: has weak keys | ||
| 30 | ** bit 3 - for tables: has weak values | ||
| 31 | ** bit 4 - for strings: is fixed (should not be collected) | ||
| 32 | */ | ||
| 33 | |||
| 34 | #define WHITEBIT 0 | ||
| 35 | #define BLACKBIT 1 | ||
| 36 | #define FINALIZEDBIT 2 | ||
| 37 | #define KEYWEAKBIT 2 | ||
| 38 | #define VALUEWEAKBIT 3 | ||
| 39 | #define FIXEDBIT 4 | ||
| 40 | |||
| 41 | |||
| 42 | |||
| 14 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ | 43 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ |
| 15 | luaC_collectgarbage(L); } | 44 | luaC_collectgarbage(L); } |
| 16 | 45 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.78 2002/12/04 17:38:31 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.79 2003/04/28 19:26:16 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -91,7 +91,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 91 | Udata *luaS_newudata (lua_State *L, size_t s) { | 91 | Udata *luaS_newudata (lua_State *L, size_t s) { |
| 92 | Udata *u; | 92 | Udata *u; |
| 93 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); | 93 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); |
| 94 | u->uv.marked = (1<<1); /* is not finalized */ | 94 | u->uv.marked = 0; /* is not finalized */ |
| 95 | u->uv.tt = LUA_TUSERDATA; | 95 | u->uv.tt = LUA_TUSERDATA; |
| 96 | u->uv.len = s; | 96 | u->uv.len = s; |
| 97 | u->uv.metatable = hvalue(defaultmeta(L)); | 97 | u->uv.metatable = hvalue(defaultmeta(L)); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.36 2002/04/30 13:01:48 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.37 2002/08/16 14:45:55 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -8,11 +8,11 @@ | |||
| 8 | #define lstring_h | 8 | #define lstring_h |
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | #include "lgc.h" | ||
| 11 | #include "lobject.h" | 12 | #include "lobject.h" |
| 12 | #include "lstate.h" | 13 | #include "lstate.h" |
| 13 | 14 | ||
| 14 | 15 | ||
| 15 | |||
| 16 | #define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ | 16 | #define sizestring(l) (cast(lu_mem, sizeof(union TString))+ \ |
| 17 | (cast(lu_mem, l)+1)*sizeof(char)) | 17 | (cast(lu_mem, l)+1)*sizeof(char)) |
| 18 | 18 | ||
| @@ -22,7 +22,7 @@ | |||
| 22 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 22 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
| 23 | (sizeof(s)/sizeof(char))-1)) | 23 | (sizeof(s)/sizeof(char))-1)) |
| 24 | 24 | ||
| 25 | #define luaS_fix(s) ((s)->tsv.marked |= (1<<4)) | 25 | #define luaS_fix(s) setbit((s)->tsv.marked, FIXEDBIT) |
| 26 | 26 | ||
| 27 | void luaS_resize (lua_State *L, int newsize); | 27 | void luaS_resize (lua_State *L, int newsize); |
| 28 | Udata *luaS_newudata (lua_State *L, size_t s); | 28 | Udata *luaS_newudata (lua_State *L, size_t s); |
