aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-10-23 14:26:37 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-10-23 14:26:37 -0200
commit907368ead5978b689a97118b75e89a2095122530 (patch)
treeed428793e87ab4a3c8de49be5586878af54c8d34
parent81489beea1a201b58dba964b6bbfd263f3683f25 (diff)
downloadlua-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.c10
-rw-r--r--lfunc.c8
-rw-r--r--lgc.c22
-rw-r--r--lgc.h4
-rw-r--r--lobject.c5
-rw-r--r--lobject.h9
-rw-r--r--lstring.c13
-rw-r--r--ltable.c17
8 files changed, 54 insertions, 34 deletions
diff --git a/ldo.c b/ldo.c
index f10d614c..8bf43215 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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;
diff --git a/lfunc.c b/lfunc.c
index 4e802cee..a29894e2 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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
14GCnode luaF_root = {NULL, 0}; 16GCnode luaF_root = {NULL, 0};
15GCnode luaF_rootcl = {NULL, 0}; 17GCnode 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 }
diff --git a/lgc.c b/lgc.c
index 627db17d..0ea948f6 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
255long luaC_threshold = GARBAGE_BLOCK; 254unsigned long luaC_threshold = GARBAGE_BLOCK;
256 255
257 256
258static void markall (void) 257static void markall (void)
@@ -266,7 +265,7 @@ static void markall (void)
266 265
267long lua_collectgarbage (long limit) 266long 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
295void luaC_checkGC (void) 295void 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
diff --git a/lgc.h b/lgc.h
index fdf75d05..ea669aa2 100644
--- a/lgc.h
+++ b/lgc.h
@@ -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
14extern long luaC_threshold; 14extern unsigned long luaC_threshold;
15 15
16void luaC_checkGC (void); 16void luaC_checkGC (void);
17TObject* luaC_getref (int ref); 17TObject* luaC_getref (int ref);
diff --git a/lobject.c b/lobject.c
index f8e942b8..71579156 100644
--- a/lobject.c
+++ b/lobject.c
@@ -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
20long luaO_nentities = 0; 20unsigned 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
69void luaO_insertlist (GCnode *root, GCnode *node) 69void 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;
diff --git a/lobject.h b/lobject.h
index d07436ad..ee97f8cd 100644
--- a/lobject.h
+++ b/lobject.h
@@ -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
161extern long luaO_nentities; 161/*
162** a gross estimation of number of memory "blocks" allocated
163** (a block is *roughly* 32 bytes)
164*/
165extern unsigned long luaO_nblocks;
166
162extern char *luaO_typenames[]; 167extern char *luaO_typenames[];
163 168
164int luaO_equalObj (TObject *t1, TObject *t2); 169int luaO_equalObj (TObject *t1, TObject *t2);
diff --git a/lstring.c b/lstring.c
index 1b82cf20..cc67c66d 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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
19GCnode luaS_root = {NULL, 0}; /* list of global variables */ 22GCnode 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 }
diff --git a/ltable.c b/ltable.c
index a894c3fa..71d49dcb 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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*/
76static Node *hashnodecreate (int nhash) 78static 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