diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-23 14:26:37 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1997-10-23 14:26:37 -0200 |
commit | 907368ead5978b689a97118b75e89a2095122530 (patch) | |
tree | ed428793e87ab4a3c8de49be5586878af54c8d34 | |
parent | 81489beea1a201b58dba964b6bbfd263f3683f25 (diff) | |
download | lua-907368ead5978b689a97118b75e89a2095122530.tar.gz lua-907368ead5978b689a97118b75e89a2095122530.tar.bz2 lua-907368ead5978b689a97118b75e89a2095122530.zip |
GC now considers an "estimate" of object size, instead of just the number
of objects.
-rw-r--r-- | ldo.c | 10 | ||||
-rw-r--r-- | lfunc.c | 8 | ||||
-rw-r--r-- | lgc.c | 22 | ||||
-rw-r--r-- | lgc.h | 4 | ||||
-rw-r--r-- | lobject.c | 5 | ||||
-rw-r--r-- | lobject.h | 9 | ||||
-rw-r--r-- | lstring.c | 13 | ||||
-rw-r--r-- | ltable.c | 17 |
8 files changed, 54 insertions, 34 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -140,7 +140,7 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) | |||
140 | 140 | ||
141 | 141 | ||
142 | /* | 142 | /* |
143 | ** Call a C function. luaD_Cstack.base will point to the luaD_stack.top of the luaD_stack.stack, | 143 | ** Call a C function. luaD_Cstack.base will point to the top of the stack, |
144 | ** and luaD_Cstack.num is the number of parameters. Returns an index | 144 | ** and luaD_Cstack.num is the number of parameters. Returns an index |
145 | ** to the first result from C. | 145 | ** to the first result from C. |
146 | */ | 146 | */ |
@@ -151,7 +151,7 @@ static StkId callC (lua_CFunction func, StkId base) | |||
151 | luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; | 151 | luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; |
152 | /* incorporate parameters on the luaD_stack.stack */ | 152 | /* incorporate parameters on the luaD_stack.stack */ |
153 | luaD_Cstack.lua2C = base; | 153 | luaD_Cstack.lua2C = base; |
154 | luaD_Cstack.base = base+luaD_Cstack.num; /* == luaD_stack.top-luaD_stack.stack */ | 154 | luaD_Cstack.base = base+luaD_Cstack.num; /* == top-stack */ |
155 | if (lua_callhook) | 155 | if (lua_callhook) |
156 | luaD_callHook(base, LUA_T_CMARK, 0); | 156 | luaD_callHook(base, LUA_T_CMARK, 0); |
157 | (*func)(); | 157 | (*func)(); |
@@ -347,12 +347,12 @@ static int do_main (ZIO *z, char *chunkname, int bin) | |||
347 | { | 347 | { |
348 | int status; | 348 | int status; |
349 | do { | 349 | do { |
350 | long old_entities = (luaC_checkGC(), luaO_nentities); | 350 | long old_blocks = (luaC_checkGC(), luaO_nblocks); |
351 | status = protectedparser(z, chunkname, bin); | 351 | status = protectedparser(z, chunkname, bin); |
352 | if (status == 1) return 1; /* error */ | 352 | if (status == 1) return 1; /* error */ |
353 | else if (status == 2) return 0; /* 'natural' end */ | 353 | else if (status == 2) return 0; /* 'natural' end */ |
354 | else { | 354 | else { |
355 | long newelems2 = 2*(luaO_nentities-old_entities); | 355 | unsigned long newelems2 = 2*(luaO_nblocks-old_blocks); |
356 | luaC_threshold += newelems2; | 356 | luaC_threshold += newelems2; |
357 | status = luaD_protectedrun(MULT_RET); | 357 | status = luaD_protectedrun(MULT_RET); |
358 | luaC_threshold -= newelems2; | 358 | luaC_threshold -= newelems2; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ |
3 | ** Lua Funcion auxiliar | 3 | ** Lua Funcion auxiliar |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -10,6 +10,8 @@ | |||
10 | #include "lfunc.h" | 10 | #include "lfunc.h" |
11 | #include "lmem.h" | 11 | #include "lmem.h" |
12 | 12 | ||
13 | #define gcsizeproto(p) 5 | ||
14 | #define gcsizeclosure(c) 1 | ||
13 | 15 | ||
14 | GCnode luaF_root = {NULL, 0}; | 16 | GCnode luaF_root = {NULL, 0}; |
15 | GCnode luaF_rootcl = {NULL, 0}; | 17 | GCnode luaF_rootcl = {NULL, 0}; |
@@ -20,6 +22,7 @@ Closure *luaF_newclosure (int nelems) | |||
20 | { | 22 | { |
21 | Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); | 23 | Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); |
22 | luaO_insertlist(&luaF_rootcl, (GCnode *)c); | 24 | luaO_insertlist(&luaF_rootcl, (GCnode *)c); |
25 | luaO_nblocks += gcsizeclosure(c); | ||
23 | return c; | 26 | return c; |
24 | } | 27 | } |
25 | 28 | ||
@@ -34,6 +37,7 @@ TProtoFunc *luaF_newproto (void) | |||
34 | f->nconsts = 0; | 37 | f->nconsts = 0; |
35 | f->locvars = NULL; | 38 | f->locvars = NULL; |
36 | luaO_insertlist(&luaF_root, (GCnode *)f); | 39 | luaO_insertlist(&luaF_root, (GCnode *)f); |
40 | luaO_nblocks += gcsizeproto(f); | ||
37 | return f; | 41 | return f; |
38 | } | 42 | } |
39 | 43 | ||
@@ -52,6 +56,7 @@ void luaF_freeproto (TProtoFunc *l) | |||
52 | { | 56 | { |
53 | while (l) { | 57 | while (l) { |
54 | TProtoFunc *next = (TProtoFunc *)l->head.next; | 58 | TProtoFunc *next = (TProtoFunc *)l->head.next; |
59 | luaO_nblocks -= gcsizeproto(l); | ||
55 | freefunc(l); | 60 | freefunc(l); |
56 | l = next; | 61 | l = next; |
57 | } | 62 | } |
@@ -62,6 +67,7 @@ void luaF_freeclosure (Closure *l) | |||
62 | { | 67 | { |
63 | while (l) { | 68 | while (l) { |
64 | Closure *next = (Closure *)l->head.next; | 69 | Closure *next = (Closure *)l->head.next; |
70 | luaO_nblocks -= gcsizeclosure(l); | ||
65 | luaM_free(l); | 71 | luaM_free(l); |
66 | l = next; | 72 | l = next; |
67 | } | 73 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.3 1997/09/26 16:46:20 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.4 1997/10/16 10:59:34 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 | */ |
@@ -148,7 +148,6 @@ static GCnode *listcollect (GCnode *l) | |||
148 | next->next = frees; | 148 | next->next = frees; |
149 | frees = next; | 149 | frees = next; |
150 | next = l->next; | 150 | next = l->next; |
151 | --luaO_nentities; | ||
152 | } | 151 | } |
153 | l = next; | 152 | l = next; |
154 | } | 153 | } |
@@ -252,7 +251,7 @@ static void call_nilIM (void) | |||
252 | 251 | ||
253 | #define GARBAGE_BLOCK 150 | 252 | #define GARBAGE_BLOCK 150 |
254 | 253 | ||
255 | long luaC_threshold = GARBAGE_BLOCK; | 254 | unsigned long luaC_threshold = GARBAGE_BLOCK; |
256 | 255 | ||
257 | 256 | ||
258 | static void markall (void) | 257 | static void markall (void) |
@@ -266,7 +265,7 @@ static void markall (void) | |||
266 | 265 | ||
267 | long lua_collectgarbage (long limit) | 266 | long lua_collectgarbage (long limit) |
268 | { | 267 | { |
269 | long recovered = luaO_nentities; /* to subtract luaM_new value after gc */ | 268 | unsigned long recovered = luaO_nblocks; /* to subtract nblocks after gc */ |
270 | Hash *freetable; | 269 | Hash *freetable; |
271 | TaggedString *freestr; | 270 | TaggedString *freestr; |
272 | TProtoFunc *freefunc; | 271 | TProtoFunc *freefunc; |
@@ -277,24 +276,25 @@ long lua_collectgarbage (long limit) | |||
277 | freetable = (Hash *)listcollect(&luaH_root); | 276 | freetable = (Hash *)listcollect(&luaH_root); |
278 | freefunc = (TProtoFunc *)listcollect(&luaF_root); | 277 | freefunc = (TProtoFunc *)listcollect(&luaF_root); |
279 | freeclos = (Closure *)listcollect(&luaF_rootcl); | 278 | freeclos = (Closure *)listcollect(&luaF_rootcl); |
280 | recovered = recovered-luaO_nentities; | 279 | luaC_threshold *= 4; /* to avoid GC during GC */ |
281 | /*printf("==total %ld coletados %ld\n", luaO_nentities+recovered, recovered);*/ | 280 | hashcallIM(freetable); /* GC tag methods for tables */ |
282 | luaC_threshold = (limit == 0) ? 2*luaO_nentities : luaO_nentities+limit; | 281 | strcallIM(freestr); /* GC tag methods for userdata */ |
283 | hashcallIM(freetable); | 282 | call_nilIM(); /* GC tag method for nil (signal end of GC) */ |
284 | strcallIM(freestr); | ||
285 | call_nilIM(); | ||
286 | luaH_free(freetable); | 283 | luaH_free(freetable); |
287 | luaS_free(freestr); | 284 | luaS_free(freestr); |
288 | luaF_freeproto(freefunc); | 285 | luaF_freeproto(freefunc); |
289 | luaF_freeclosure(freeclos); | 286 | luaF_freeclosure(freeclos); |
290 | luaM_clearbuffer(); | 287 | luaM_clearbuffer(); |
288 | recovered = recovered-luaO_nblocks; | ||
289 | /*printf("==total %ld coletados %ld\n", luaO_nblocks+recovered, recovered);*/ | ||
290 | luaC_threshold = (limit == 0) ? 2*luaO_nblocks : luaO_nblocks+limit; | ||
291 | return recovered; | 291 | return recovered; |
292 | } | 292 | } |
293 | 293 | ||
294 | 294 | ||
295 | void luaC_checkGC (void) | 295 | void luaC_checkGC (void) |
296 | { | 296 | { |
297 | if (luaO_nentities >= luaC_threshold) | 297 | if (luaO_nblocks >= luaC_threshold) |
298 | lua_collectgarbage(0); | 298 | lua_collectgarbage(0); |
299 | } | 299 | } |
300 | 300 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: $ | 2 | ** $Id: lgc.h,v 1.1 1997/09/16 19:25:59 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,7 +11,7 @@ | |||
11 | #include "lobject.h" | 11 | #include "lobject.h" |
12 | 12 | ||
13 | 13 | ||
14 | extern long luaC_threshold; | 14 | extern unsigned long luaC_threshold; |
15 | 15 | ||
16 | void luaC_checkGC (void); | 16 | void luaC_checkGC (void); |
17 | TObject* luaC_getref (int ref); | 17 | TObject* luaC_getref (int ref); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.3 1997/10/16 20:07:40 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -17,7 +17,7 @@ char *luaO_typenames[] = { /* ORDER LUA_T */ | |||
17 | }; | 17 | }; |
18 | 18 | ||
19 | 19 | ||
20 | long luaO_nentities = 0; | 20 | unsigned long luaO_nblocks = 0; |
21 | 21 | ||
22 | 22 | ||
23 | /* hash dimensions values */ | 23 | /* hash dimensions values */ |
@@ -68,7 +68,6 @@ int luaO_findstring (char *name, char *list[]) | |||
68 | 68 | ||
69 | void luaO_insertlist (GCnode *root, GCnode *node) | 69 | void luaO_insertlist (GCnode *root, GCnode *node) |
70 | { | 70 | { |
71 | ++luaO_nentities; | ||
72 | node->next = root->next; | 71 | node->next = root->next; |
73 | root->next = node; | 72 | root->next = node; |
74 | node->marked = 0; | 73 | node->marked = 0; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.5 1997/10/16 20:07:40 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -158,7 +158,12 @@ typedef struct Hash { | |||
158 | } Hash; | 158 | } Hash; |
159 | 159 | ||
160 | 160 | ||
161 | extern long luaO_nentities; | 161 | /* |
162 | ** a gross estimation of number of memory "blocks" allocated | ||
163 | ** (a block is *roughly* 32 bytes) | ||
164 | */ | ||
165 | extern unsigned long luaO_nblocks; | ||
166 | |||
162 | extern char *luaO_typenames[]; | 167 | extern char *luaO_typenames[]; |
163 | 168 | ||
164 | int luaO_equalObj (TObject *t1, TObject *t2); | 169 | int luaO_equalObj (TObject *t1, TObject *t2); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.2 1997/09/26 15:02:26 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 | */ |
@@ -16,6 +16,9 @@ | |||
16 | #define NUM_HASHS 61 | 16 | #define NUM_HASHS 61 |
17 | 17 | ||
18 | 18 | ||
19 | #define gcsizestring(l) (1+(l/64)) | ||
20 | |||
21 | |||
19 | GCnode luaS_root = {NULL, 0}; /* list of global variables */ | 22 | GCnode luaS_root = {NULL, 0}; /* list of global variables */ |
20 | 23 | ||
21 | 24 | ||
@@ -89,16 +92,19 @@ static TaggedString *newone(char *buff, int tag, unsigned long h) | |||
89 | { | 92 | { |
90 | TaggedString *ts; | 93 | TaggedString *ts; |
91 | if (tag == LUA_T_STRING) { | 94 | if (tag == LUA_T_STRING) { |
92 | ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+strlen(buff)); | 95 | long l = strlen(buff); |
96 | ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); | ||
93 | strcpy(ts->str, buff); | 97 | strcpy(ts->str, buff); |
94 | ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */ | 98 | ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */ |
95 | ts->constindex = 0; | 99 | ts->constindex = 0; |
100 | luaO_nblocks += gcsizestring(l); | ||
96 | } | 101 | } |
97 | else { | 102 | else { |
98 | ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)); | 103 | ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)); |
99 | ts->u.d.v = buff; | 104 | ts->u.d.v = buff; |
100 | ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; | 105 | ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; |
101 | ts->constindex = -1; /* tag -> this is a userdata */ | 106 | ts->constindex = -1; /* tag -> this is a userdata */ |
107 | luaO_nblocks++; | ||
102 | } | 108 | } |
103 | ts->head.marked = 0; | 109 | ts->head.marked = 0; |
104 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ | 110 | ts->head.next = (GCnode *)ts; /* signal it is in no list */ |
@@ -126,7 +132,6 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb) | |||
126 | i = (i+1)%tb->size; | 132 | i = (i+1)%tb->size; |
127 | } | 133 | } |
128 | /* not found */ | 134 | /* not found */ |
129 | ++luaO_nentities; | ||
130 | if (j != -1) /* is there an EMPTY space? */ | 135 | if (j != -1) /* is there an EMPTY space? */ |
131 | i = j; | 136 | i = j; |
132 | else | 137 | else |
@@ -158,6 +163,7 @@ void luaS_free (TaggedString *l) | |||
158 | { | 163 | { |
159 | while (l) { | 164 | while (l) { |
160 | TaggedString *next = (TaggedString *)l->head.next; | 165 | TaggedString *next = (TaggedString *)l->head.next; |
166 | luaO_nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str)); | ||
161 | luaM_free(l); | 167 | luaM_free(l); |
162 | l = next; | 168 | l = next; |
163 | } | 169 | } |
@@ -196,7 +202,6 @@ TaggedString *luaS_collector (void) | |||
196 | t->head.next = (GCnode *)frees; | 202 | t->head.next = (GCnode *)frees; |
197 | frees = t; | 203 | frees = t; |
198 | tb->hash[j] = &EMPTY; | 204 | tb->hash[j] = &EMPTY; |
199 | --luaO_nentities; | ||
200 | } | 205 | } |
201 | } | 206 | } |
202 | } | 207 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.3 1997/10/18 16:29:15 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -13,6 +13,8 @@ | |||
13 | #include "lua.h" | 13 | #include "lua.h" |
14 | 14 | ||
15 | 15 | ||
16 | #define gcsize(n) (1+(n/16)) | ||
17 | |||
16 | #define nuse(t) ((t)->nuse) | 18 | #define nuse(t) ((t)->nuse) |
17 | #define nodevector(t) ((t)->node) | 19 | #define nodevector(t) ((t)->node) |
18 | 20 | ||
@@ -75,11 +77,11 @@ static int present (Hash *t, TObject *key) | |||
75 | */ | 77 | */ |
76 | static Node *hashnodecreate (int nhash) | 78 | static Node *hashnodecreate (int nhash) |
77 | { | 79 | { |
78 | int i; | 80 | Node *v = luaM_newvector(nhash, Node); |
79 | Node *v = luaM_newvector (nhash, Node); | 81 | int i; |
80 | for (i=0; i<nhash; i++) | 82 | for (i=0; i<nhash; i++) |
81 | ttype(ref(&v[i])) = LUA_T_NIL; | 83 | ttype(ref(&v[i])) = LUA_T_NIL; |
82 | return v; | 84 | return v; |
83 | } | 85 | } |
84 | 86 | ||
85 | /* | 87 | /* |
@@ -96,6 +98,7 @@ void luaH_free (Hash *frees) | |||
96 | { | 98 | { |
97 | while (frees) { | 99 | while (frees) { |
98 | Hash *next = (Hash *)frees->head.next; | 100 | Hash *next = (Hash *)frees->head.next; |
101 | luaO_nblocks -= gcsize(frees->nhash); | ||
99 | hashdelete(frees); | 102 | hashdelete(frees); |
100 | frees = next; | 103 | frees = next; |
101 | } | 104 | } |
@@ -111,6 +114,7 @@ Hash *luaH_new (int nhash) | |||
111 | nuse(t) = 0; | 114 | nuse(t) = 0; |
112 | t->htag = TagDefault; | 115 | t->htag = TagDefault; |
113 | luaO_insertlist(&luaH_root, (GCnode *)t); | 116 | luaO_insertlist(&luaH_root, (GCnode *)t); |
117 | luaO_nblocks += gcsize(nhash); | ||
114 | return t; | 118 | return t; |
115 | } | 119 | } |
116 | 120 | ||
@@ -144,6 +148,7 @@ static void rehash (Hash *t) | |||
144 | if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) | 148 | if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) |
145 | *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ | 149 | *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ |
146 | } | 150 | } |
151 | luaO_nblocks += gcsize(t->nhash)-gcsize(nold); | ||
147 | luaM_free(vold); | 152 | luaM_free(vold); |
148 | } | 153 | } |
149 | 154 | ||