From 907368ead5978b689a97118b75e89a2095122530 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 23 Oct 1997 14:26:37 -0200 Subject: [PATCH] GC now considers an "estimate" of object size, instead of just the number of objects. --- ldo.c | 10 +++++----- lfunc.c | 8 +++++++- lgc.c | 22 +++++++++++----------- lgc.h | 4 ++-- lobject.c | 5 ++--- lobject.h | 9 +++++++-- lstring.c | 13 +++++++++---- ltable.c | 17 +++++++++++------ 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 @@ /* -** $Id: ldo.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ +** $Id: ldo.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -140,7 +140,7 @@ void luaD_callHook (StkId base, lua_Type type, int isreturn) /* -** Call a C function. luaD_Cstack.base will point to the luaD_stack.top of the luaD_stack.stack, +** Call a C function. luaD_Cstack.base will point to the top of the stack, ** and luaD_Cstack.num is the number of parameters. Returns an index ** to the first result from C. */ @@ -151,7 +151,7 @@ static StkId callC (lua_CFunction func, StkId base) luaD_Cstack.num = (luaD_stack.top-luaD_stack.stack) - base; /* incorporate parameters on the luaD_stack.stack */ luaD_Cstack.lua2C = base; - luaD_Cstack.base = base+luaD_Cstack.num; /* == luaD_stack.top-luaD_stack.stack */ + luaD_Cstack.base = base+luaD_Cstack.num; /* == top-stack */ if (lua_callhook) luaD_callHook(base, LUA_T_CMARK, 0); (*func)(); @@ -347,12 +347,12 @@ static int do_main (ZIO *z, char *chunkname, int bin) { int status; do { - long old_entities = (luaC_checkGC(), luaO_nentities); + long old_blocks = (luaC_checkGC(), luaO_nblocks); status = protectedparser(z, chunkname, bin); if (status == 1) return 1; /* error */ else if (status == 2) return 0; /* 'natural' end */ else { - long newelems2 = 2*(luaO_nentities-old_entities); + unsigned long newelems2 = 2*(luaO_nblocks-old_blocks); luaC_threshold += newelems2; status = luaD_protectedrun(MULT_RET); 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 @@ /* -** $Id: lfunc.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ +** $Id: lfunc.c,v 1.3 1997/10/16 10:59:34 roberto Exp roberto $ ** Lua Funcion auxiliar ** See Copyright Notice in lua.h */ @@ -10,6 +10,8 @@ #include "lfunc.h" #include "lmem.h" +#define gcsizeproto(p) 5 +#define gcsizeclosure(c) 1 GCnode luaF_root = {NULL, 0}; GCnode luaF_rootcl = {NULL, 0}; @@ -20,6 +22,7 @@ Closure *luaF_newclosure (int nelems) { Closure *c = (Closure *)luaM_malloc(sizeof(Closure)+nelems*sizeof(TObject)); luaO_insertlist(&luaF_rootcl, (GCnode *)c); + luaO_nblocks += gcsizeclosure(c); return c; } @@ -34,6 +37,7 @@ TProtoFunc *luaF_newproto (void) f->nconsts = 0; f->locvars = NULL; luaO_insertlist(&luaF_root, (GCnode *)f); + luaO_nblocks += gcsizeproto(f); return f; } @@ -52,6 +56,7 @@ void luaF_freeproto (TProtoFunc *l) { while (l) { TProtoFunc *next = (TProtoFunc *)l->head.next; + luaO_nblocks -= gcsizeproto(l); freefunc(l); l = next; } @@ -62,6 +67,7 @@ void luaF_freeclosure (Closure *l) { while (l) { Closure *next = (Closure *)l->head.next; + luaO_nblocks -= gcsizeclosure(l); luaM_free(l); l = next; } diff --git a/lgc.c b/lgc.c index 627db17d..0ea948f6 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.3 1997/09/26 16:46:20 roberto Exp roberto $ +** $Id: lgc.c,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -148,7 +148,6 @@ static GCnode *listcollect (GCnode *l) next->next = frees; frees = next; next = l->next; - --luaO_nentities; } l = next; } @@ -252,7 +251,7 @@ static void call_nilIM (void) #define GARBAGE_BLOCK 150 -long luaC_threshold = GARBAGE_BLOCK; +unsigned long luaC_threshold = GARBAGE_BLOCK; static void markall (void) @@ -266,7 +265,7 @@ static void markall (void) long lua_collectgarbage (long limit) { - long recovered = luaO_nentities; /* to subtract luaM_new value after gc */ + unsigned long recovered = luaO_nblocks; /* to subtract nblocks after gc */ Hash *freetable; TaggedString *freestr; TProtoFunc *freefunc; @@ -277,24 +276,25 @@ long lua_collectgarbage (long limit) freetable = (Hash *)listcollect(&luaH_root); freefunc = (TProtoFunc *)listcollect(&luaF_root); freeclos = (Closure *)listcollect(&luaF_rootcl); - recovered = recovered-luaO_nentities; -/*printf("==total %ld coletados %ld\n", luaO_nentities+recovered, recovered);*/ - luaC_threshold = (limit == 0) ? 2*luaO_nentities : luaO_nentities+limit; - hashcallIM(freetable); - strcallIM(freestr); - call_nilIM(); + luaC_threshold *= 4; /* to avoid GC during GC */ + hashcallIM(freetable); /* GC tag methods for tables */ + strcallIM(freestr); /* GC tag methods for userdata */ + call_nilIM(); /* GC tag method for nil (signal end of GC) */ luaH_free(freetable); luaS_free(freestr); luaF_freeproto(freefunc); luaF_freeclosure(freeclos); luaM_clearbuffer(); + recovered = recovered-luaO_nblocks; +/*printf("==total %ld coletados %ld\n", luaO_nblocks+recovered, recovered);*/ + luaC_threshold = (limit == 0) ? 2*luaO_nblocks : luaO_nblocks+limit; return recovered; } void luaC_checkGC (void) { - if (luaO_nentities >= luaC_threshold) + if (luaO_nblocks >= luaC_threshold) lua_collectgarbage(0); } diff --git a/lgc.h b/lgc.h index fdf75d05..ea669aa2 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: $ +** $Id: lgc.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -11,7 +11,7 @@ #include "lobject.h" -extern long luaC_threshold; +extern unsigned long luaC_threshold; void luaC_checkGC (void); TObject* 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 @@ /* -** $Id: lobject.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ +** $Id: lobject.c,v 1.3 1997/10/16 20:07:40 roberto Exp roberto $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -17,7 +17,7 @@ char *luaO_typenames[] = { /* ORDER LUA_T */ }; -long luaO_nentities = 0; +unsigned long luaO_nblocks = 0; /* hash dimensions values */ @@ -68,7 +68,6 @@ int luaO_findstring (char *name, char *list[]) void luaO_insertlist (GCnode *root, GCnode *node) { - ++luaO_nentities; node->next = root->next; root->next = node; 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 @@ /* -** $Id: lobject.h,v 1.4 1997/10/16 10:59:34 roberto Exp roberto $ +** $Id: lobject.h,v 1.5 1997/10/16 20:07:40 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -158,7 +158,12 @@ typedef struct Hash { } Hash; -extern long luaO_nentities; +/* +** a gross estimation of number of memory "blocks" allocated +** (a block is *roughly* 32 bytes) +*/ +extern unsigned long luaO_nblocks; + extern char *luaO_typenames[]; int 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 @@ /* -** $Id: lstring.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $ +** $Id: lstring.c,v 1.2 1997/09/26 15:02:26 roberto Exp roberto $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -16,6 +16,9 @@ #define NUM_HASHS 61 +#define gcsizestring(l) (1+(l/64)) + + GCnode luaS_root = {NULL, 0}; /* list of global variables */ @@ -89,16 +92,19 @@ static TaggedString *newone(char *buff, int tag, unsigned long h) { TaggedString *ts; if (tag == LUA_T_STRING) { - ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+strlen(buff)); + long l = strlen(buff); + ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); strcpy(ts->str, buff); ts->u.globalval.ttype = LUA_T_NIL; /* initialize global value */ ts->constindex = 0; + luaO_nblocks += gcsizestring(l); } else { ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)); ts->u.d.v = buff; ts->u.d.tag = tag == LUA_ANYTAG ? 0 : tag; ts->constindex = -1; /* tag -> this is a userdata */ + luaO_nblocks++; } ts->head.marked = 0; ts->head.next = (GCnode *)ts; /* signal it is in no list */ @@ -126,7 +132,6 @@ static TaggedString *insert (char *buff, int tag, stringtable *tb) i = (i+1)%tb->size; } /* not found */ - ++luaO_nentities; if (j != -1) /* is there an EMPTY space? */ i = j; else @@ -158,6 +163,7 @@ void luaS_free (TaggedString *l) { while (l) { TaggedString *next = (TaggedString *)l->head.next; + luaO_nblocks -= (l->constindex == -1) ? 1 : gcsizestring(strlen(l->str)); luaM_free(l); l = next; } @@ -196,7 +202,6 @@ TaggedString *luaS_collector (void) t->head.next = (GCnode *)frees; frees = t; tb->hash[j] = ∅ - --luaO_nentities; } } } diff --git a/ltable.c b/ltable.c index a894c3fa..71d49dcb 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.2 1997/09/26 16:46:20 roberto Exp roberto $ +** $Id: ltable.c,v 1.3 1997/10/18 16:29:15 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -13,6 +13,8 @@ #include "lua.h" +#define gcsize(n) (1+(n/16)) + #define nuse(t) ((t)->nuse) #define nodevector(t) ((t)->node) @@ -75,11 +77,11 @@ static int present (Hash *t, TObject *key) */ static Node *hashnodecreate (int nhash) { - int i; - Node *v = luaM_newvector (nhash, Node); - for (i=0; ihead.next; + luaO_nblocks -= gcsize(frees->nhash); hashdelete(frees); frees = next; } @@ -111,6 +114,7 @@ Hash *luaH_new (int nhash) nuse(t) = 0; t->htag = TagDefault; luaO_insertlist(&luaH_root, (GCnode *)t); + luaO_nblocks += gcsize(nhash); return t; } @@ -144,6 +148,7 @@ static void rehash (Hash *t) if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) *node(t, present(t, ref(n))) = *n; /* copy old node to luaM_new hash */ } + luaO_nblocks += gcsize(t->nhash)-gcsize(nold); luaM_free(vold); }