mirror of
https://github.com/lua/lua.git
synced 2025-01-14 05:43:00 +08:00
GC now considers an "estimate" of object size, instead of just the number
of objects.
This commit is contained in:
parent
81489beea1
commit
907368ead5
10
ldo.c
10
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;
|
||||
|
8
lfunc.c
8
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;
|
||||
}
|
||||
|
22
lgc.c
22
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);
|
||||
}
|
||||
|
||||
|
4
lgc.h
4
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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
13
lstring.c
13
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
17
ltable.c
17
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; i<nhash; i++)
|
||||
ttype(ref(&v[i])) = LUA_T_NIL;
|
||||
return v;
|
||||
Node *v = luaM_newvector(nhash, Node);
|
||||
int i;
|
||||
for (i=0; i<nhash; i++)
|
||||
ttype(ref(&v[i])) = LUA_T_NIL;
|
||||
return v;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -96,6 +98,7 @@ void luaH_free (Hash *frees)
|
||||
{
|
||||
while (frees) {
|
||||
Hash *next = (Hash *)frees->head.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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user