diff options
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 74 |
1 files changed, 33 insertions, 41 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.6 1997/10/24 17:17:24 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.7 1997/11/03 20:45:23 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 | */ |
@@ -10,6 +10,7 @@ | |||
10 | #include "lgc.h" | 10 | #include "lgc.h" |
11 | #include "lmem.h" | 11 | #include "lmem.h" |
12 | #include "lobject.h" | 12 | #include "lobject.h" |
13 | #include "lstate.h" | ||
13 | #include "lstring.h" | 14 | #include "lstring.h" |
14 | #include "ltable.h" | 15 | #include "ltable.h" |
15 | #include "ltm.h" | 16 | #include "ltm.h" |
@@ -27,12 +28,6 @@ static int markobject (TObject *o); | |||
27 | ** ======================================================= | 28 | ** ======================================================= |
28 | */ | 29 | */ |
29 | 30 | ||
30 | static struct ref { | ||
31 | TObject o; | ||
32 | enum {LOCK, HOLD, FREE, COLLECTED} status; | ||
33 | } *refArray = NULL; | ||
34 | static int refSize = 0; | ||
35 | |||
36 | 31 | ||
37 | int luaC_ref (TObject *o, int lock) | 32 | int luaC_ref (TObject *o, int lock) |
38 | { | 33 | { |
@@ -40,18 +35,19 @@ int luaC_ref (TObject *o, int lock) | |||
40 | if (ttype(o) == LUA_T_NIL) | 35 | if (ttype(o) == LUA_T_NIL) |
41 | ref = -1; /* special ref for nil */ | 36 | ref = -1; /* special ref for nil */ |
42 | else { | 37 | else { |
43 | for (ref=0; ref<refSize; ref++) | 38 | for (ref=0; ref<L->refSize; ref++) |
44 | if (refArray[ref].status == FREE) | 39 | if (L->refArray[ref].status == FREE) |
45 | goto found; | 40 | goto found; |
46 | /* no more empty spaces */ { | 41 | /* no more empty spaces */ { |
47 | int oldSize = refSize; | 42 | int oldSize = L->refSize; |
48 | refSize = luaM_growvector(&refArray, refSize, struct ref, refEM, MAX_WORD); | 43 | L->refSize = luaM_growvector(&L->refArray, L->refSize, struct ref, |
49 | for (ref=oldSize; ref<refSize; ref++) | 44 | refEM, MAX_WORD); |
50 | refArray[ref].status = FREE; | 45 | for (ref=oldSize; ref<L->refSize; ref++) |
46 | L->refArray[ref].status = FREE; | ||
51 | ref = oldSize; | 47 | ref = oldSize; |
52 | } found: | 48 | } found: |
53 | refArray[ref].o = *o; | 49 | L->refArray[ref].o = *o; |
54 | refArray[ref].status = lock ? LOCK : HOLD; | 50 | L->refArray[ref].status = lock ? LOCK : HOLD; |
55 | } | 51 | } |
56 | return ref; | 52 | return ref; |
57 | } | 53 | } |
@@ -59,8 +55,8 @@ int luaC_ref (TObject *o, int lock) | |||
59 | 55 | ||
60 | void lua_unref (int ref) | 56 | void lua_unref (int ref) |
61 | { | 57 | { |
62 | if (ref >= 0 && ref < refSize) | 58 | if (ref >= 0 && ref < L->refSize) |
63 | refArray[ref].status = FREE; | 59 | L->refArray[ref].status = FREE; |
64 | } | 60 | } |
65 | 61 | ||
66 | 62 | ||
@@ -68,9 +64,9 @@ TObject* luaC_getref (int ref) | |||
68 | { | 64 | { |
69 | if (ref == -1) | 65 | if (ref == -1) |
70 | return &luaO_nilobject; | 66 | return &luaO_nilobject; |
71 | if (ref >= 0 && ref < refSize && | 67 | if (ref >= 0 && ref < L->refSize && |
72 | (refArray[ref].status == LOCK || refArray[ref].status == HOLD)) | 68 | (L->refArray[ref].status == LOCK || L->refArray[ref].status == HOLD)) |
73 | return &refArray[ref].o; | 69 | return &L->refArray[ref].o; |
74 | else | 70 | else |
75 | return NULL; | 71 | return NULL; |
76 | } | 72 | } |
@@ -79,9 +75,9 @@ TObject* luaC_getref (int ref) | |||
79 | static void travlock (void) | 75 | static void travlock (void) |
80 | { | 76 | { |
81 | int i; | 77 | int i; |
82 | for (i=0; i<refSize; i++) | 78 | for (i=0; i<L->refSize; i++) |
83 | if (refArray[i].status == LOCK) | 79 | if (L->refArray[i].status == LOCK) |
84 | markobject(&refArray[i].o); | 80 | markobject(&L->refArray[i].o); |
85 | } | 81 | } |
86 | 82 | ||
87 | 83 | ||
@@ -105,9 +101,9 @@ static int ismarked (TObject *o) | |||
105 | static void invalidaterefs (void) | 101 | static void invalidaterefs (void) |
106 | { | 102 | { |
107 | int i; | 103 | int i; |
108 | for (i=0; i<refSize; i++) | 104 | for (i=0; i<L->refSize; i++) |
109 | if (refArray[i].status == HOLD && !ismarked(&refArray[i].o)) | 105 | if (L->refArray[i].status == HOLD && !ismarked(&L->refArray[i].o)) |
110 | refArray[i].status = COLLECTED; | 106 | L->refArray[i].status = COLLECTED; |
111 | } | 107 | } |
112 | 108 | ||
113 | 109 | ||
@@ -210,7 +206,7 @@ static void hashmark (Hash *h) | |||
210 | static void globalmark (void) | 206 | static void globalmark (void) |
211 | { | 207 | { |
212 | TaggedString *g; | 208 | TaggedString *g; |
213 | for (g=(TaggedString *)luaS_root.next; g; g=(TaggedString *)g->head.next) | 209 | for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) |
214 | if (g->u.globalval.ttype != LUA_T_NIL) { | 210 | if (g->u.globalval.ttype != LUA_T_NIL) { |
215 | markobject(&g->u.globalval); | 211 | markobject(&g->u.globalval); |
216 | strmark(g); /* cannot collect non nil global variables */ | 212 | strmark(g); /* cannot collect non nil global variables */ |
@@ -240,23 +236,19 @@ static int markobject (TObject *o) | |||
240 | 236 | ||
241 | 237 | ||
242 | 238 | ||
243 | #define GARBAGE_BLOCK 150 | ||
244 | |||
245 | unsigned long luaC_threshold = GARBAGE_BLOCK; | ||
246 | |||
247 | |||
248 | static void markall (void) | 239 | static void markall (void) |
249 | { | 240 | { |
250 | luaD_travstack(markobject); /* mark stack objects */ | 241 | luaD_travstack(markobject); /* mark stack objects */ |
251 | globalmark(); /* mark global variable values and names */ | 242 | globalmark(); /* mark global variable values and names */ |
252 | travlock(); /* mark locked objects */ | 243 | travlock(); /* mark locked objects */ |
244 | markobject(&L->globalbag); /* mark elements in global bag */ | ||
253 | luaT_travtagmethods(markobject); /* mark fallbacks */ | 245 | luaT_travtagmethods(markobject); /* mark fallbacks */ |
254 | } | 246 | } |
255 | 247 | ||
256 | 248 | ||
257 | long lua_collectgarbage (long limit) | 249 | long lua_collectgarbage (long limit) |
258 | { | 250 | { |
259 | unsigned long recovered = luaO_nblocks; /* to subtract nblocks after gc */ | 251 | unsigned long recovered = L->nblocks; /* to subtract nblocks after gc */ |
260 | Hash *freetable; | 252 | Hash *freetable; |
261 | TaggedString *freestr; | 253 | TaggedString *freestr; |
262 | TProtoFunc *freefunc; | 254 | TProtoFunc *freefunc; |
@@ -264,10 +256,10 @@ long lua_collectgarbage (long limit) | |||
264 | markall(); | 256 | markall(); |
265 | invalidaterefs(); | 257 | invalidaterefs(); |
266 | freestr = luaS_collector(); | 258 | freestr = luaS_collector(); |
267 | freetable = (Hash *)listcollect(&luaH_root); | 259 | freetable = (Hash *)listcollect(&(L->roottable)); |
268 | freefunc = (TProtoFunc *)listcollect(&luaF_root); | 260 | freefunc = (TProtoFunc *)listcollect(&(L->rootproto)); |
269 | freeclos = (Closure *)listcollect(&luaF_rootcl); | 261 | freeclos = (Closure *)listcollect(&(L->rootcl)); |
270 | luaC_threshold *= 4; /* to avoid GC during GC */ | 262 | L->GCthreshold *= 4; /* to avoid GC during GC */ |
271 | hashcallIM(freetable); /* GC tag methods for tables */ | 263 | hashcallIM(freetable); /* GC tag methods for tables */ |
272 | strcallIM(freestr); /* GC tag methods for userdata */ | 264 | strcallIM(freestr); /* GC tag methods for userdata */ |
273 | luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ | 265 | luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ |
@@ -276,16 +268,16 @@ long lua_collectgarbage (long limit) | |||
276 | luaF_freeproto(freefunc); | 268 | luaF_freeproto(freefunc); |
277 | luaF_freeclosure(freeclos); | 269 | luaF_freeclosure(freeclos); |
278 | luaM_clearbuffer(); | 270 | luaM_clearbuffer(); |
279 | recovered = recovered-luaO_nblocks; | 271 | recovered = recovered-L->nblocks; |
280 | /*printf("==total %ld coletados %ld\n", luaO_nblocks+recovered, recovered);*/ | 272 | /*printf("==total %ld coletados %ld\n", L->nblocks+recovered, recovered);*/ |
281 | luaC_threshold = (limit == 0) ? 2*luaO_nblocks : luaO_nblocks+limit; | 273 | L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; |
282 | return recovered; | 274 | return recovered; |
283 | } | 275 | } |
284 | 276 | ||
285 | 277 | ||
286 | void luaC_checkGC (void) | 278 | void luaC_checkGC (void) |
287 | { | 279 | { |
288 | if (luaO_nblocks >= luaC_threshold) | 280 | if (L->nblocks >= L->GCthreshold) |
289 | lua_collectgarbage(0); | 281 | lua_collectgarbage(0); |
290 | } | 282 | } |
291 | 283 | ||