summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lfunc.c4
-rw-r--r--lgc.c70
-rw-r--r--lgc.h31
-rw-r--r--lstring.c4
-rw-r--r--lstring.h6
5 files changed, 69 insertions, 46 deletions
diff --git a/lfunc.c b/lfunc.c
index 7117b783..a3cb42a1 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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);
diff --git a/lgc.c b/lgc.c
index 1ec12f1d..486e3fbc 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
68static void reallymarkobject (GCState *st, GCObject *o) { 61static 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) {
101static void marktmu (GCState *st) { 94static 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
366static int sweeplist (lua_State *L, GCObject **p, int limit) { 360static 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
384static void sweepstrings (lua_State *L, int all) { 378static 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
437void luaC_sweep (lua_State *L, int all) { 431void 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
diff --git a/lgc.h b/lgc.h
index 85f3b43e..29adec24 100644
--- a/lgc.h
+++ b/lgc.h
@@ -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
diff --git a/lstring.c b/lstring.c
index f1d7d232..1b0a0050 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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) {
91Udata *luaS_newudata (lua_State *L, size_t s) { 91Udata *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));
diff --git a/lstring.h b/lstring.h
index 13a12a5a..1fae1a58 100644
--- a/lstring.h
+++ b/lstring.h
@@ -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
27void luaS_resize (lua_State *L, int newsize); 27void luaS_resize (lua_State *L, int newsize);
28Udata *luaS_newudata (lua_State *L, size_t s); 28Udata *luaS_newudata (lua_State *L, size_t s);