diff --git a/lapi.c b/lapi.c index 39e052b4..09ab8f20 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.99 2000/09/18 19:39:26 roberto Exp roberto $ +** $Id: lapi.c,v 1.100 2000/09/27 12:51:39 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -355,6 +355,7 @@ int lua_ref (lua_State *L, int lock) { else { /* no more free places */ luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, "reference table overflow", MAX_INT); + L->nblocks += sizeof(struct Ref); ref = L->refSize++; } L->refArray[ref].o = *(L->top-1); diff --git a/lcode.c b/lcode.c index 047fb74a..724fc2e4 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.49 2000/08/15 13:18:28 roberto Exp roberto $ +** $Id: lcode.c,v 1.50 2000/08/31 14:08:27 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -420,13 +420,14 @@ void luaK_posfix (LexState *ls, BinOpr op, expdesc *v1, expdesc *v2) { static void codelineinfo (FuncState *fs) { + Proto *f = fs->f; LexState *ls = fs->ls; if (ls->lastline > fs->lastline) { - luaM_growvector(fs->L, fs->f->lineinfo, fs->nlineinfo, 2, int, + luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int, "line info overflow", MAX_INT); if (ls->lastline > fs->lastline+1) - fs->f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); - fs->f->lineinfo[fs->nlineinfo++] = fs->pc; + f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); + f->lineinfo[f->nlineinfo++] = fs->pc; fs->lastline = ls->lastline; } } diff --git a/ldo.c b/ldo.c index 8f49b595..283c3cdf 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.96 2000/09/12 13:47:39 roberto Exp roberto $ +** $Id: ldo.c,v 1.97 2000/09/25 16:22:42 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -33,6 +33,7 @@ void luaD_init (lua_State *L, int stacksize) { L->stack = luaM_newvector(L, stacksize+EXTRA_STACK, TObject); + L->nblocks += stacksize*sizeof(TObject); L->stack_last = L->stack+(stacksize-1); L->stacksize = stacksize; L->Cbase = L->top = L->stack; @@ -248,10 +249,12 @@ static int protectedparser (lua_State *L, ZIO *z, int bin) { luaC_checkGC(L); old_blocks = L->nblocks; status = luaD_runprotected(L, f_parser, &p); - if (status == LUA_ERRRUN) /* an error occurred: correct error code */ + if (status == 0) { + /* add new memory to threshould (as it probably will stay) */ + L->GCthreshold += (L->nblocks - old_blocks); + } + else if (status == LUA_ERRRUN) /* an error occurred: correct error code */ status = LUA_ERRSYNTAX; - /* add new memory to threshould (as it probably will stay) */ - L->GCthreshold += (L->nblocks - old_blocks); return status; } diff --git a/lfunc.c b/lfunc.c index 579d5e6a..73c443bb 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 1.29 2000/08/09 19:16:57 roberto Exp roberto $ +** $Id: lfunc.c,v 1.30 2000/08/22 17:44:17 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -13,19 +13,18 @@ #include "lmem.h" #include "lstate.h" -#define gcsizeproto(L, p) numblocks(L, 0, sizeof(Proto)) -#define gcsizeclosure(L, c) numblocks(L, c->nupvalues, sizeof(Closure)) +#define sizeclosure(n) (sizeof(Closure) + (lint32)sizeof(TObject)*((n)-1)) Closure *luaF_newclosure (lua_State *L, int nelems) { - Closure *c = (Closure *)luaM_malloc(L, sizeof(Closure) + - (lint32)sizeof(TObject)*(nelems-1)); + lint32 size = sizeclosure(nelems); + Closure *c = (Closure *)luaM_malloc(L, size); c->next = L->rootcl; L->rootcl = c; c->mark = c; c->nupvalues = nelems; - L->nblocks += gcsizeclosure(L, c); + L->nblocks += size; return c; } @@ -33,7 +32,9 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { Proto *luaF_newproto (lua_State *L) { Proto *f = luaM_new(L, Proto); f->code = NULL; + f->ncode = 0; f->lineinfo = NULL; + f->nlineinfo = 0; f->lineDefined = 0; f->source = NULL; f->kstr = NULL; @@ -47,13 +48,30 @@ Proto *luaF_newproto (lua_State *L) { f->next = L->rootproto; L->rootproto = f; f->marked = 0; - L->nblocks += gcsizeproto(L, f); return f; } +static size_t protosize (Proto *f) { + return sizeof(Proto) + + f->nknum*sizeof(Number) + + f->nkstr*sizeof(TString *) + + f->nkproto*sizeof(Proto *) + + f->ncode*sizeof(Instruction) + + f->nlocvars*sizeof(struct LocVar) + + f->nlineinfo*sizeof(int); +} + + +void luaF_protook (lua_State *L, Proto *f, int pc) { + f->ncode = pc; /* signal that proto was properly created */ + L->nblocks += protosize(f); +} + + void luaF_freeproto (lua_State *L, Proto *f) { - L->nblocks -= gcsizeproto(L, f); + if (f->ncode > 0) /* function was properly created? */ + L->nblocks -= protosize(f); luaM_free(L, f->code); luaM_free(L, f->locvars); luaM_free(L, f->kstr); @@ -65,7 +83,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { void luaF_freeclosure (lua_State *L, Closure *c) { - L->nblocks -= gcsizeclosure(L, c); + L->nblocks -= sizeclosure(c->nupvalues); luaM_free(L, c); } diff --git a/lfunc.h b/lfunc.h index 1182e3fa..3a9bc990 100644 --- a/lfunc.h +++ b/lfunc.h @@ -1,5 +1,5 @@ /* -** $Id: lfunc.h,v 1.11 2000/03/10 18:37:44 roberto Exp roberto $ +** $Id: lfunc.h,v 1.12 2000/06/26 19:28:31 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -13,6 +13,7 @@ Proto *luaF_newproto (lua_State *L); +void luaF_protook (lua_State *L, Proto *f, int pc); Closure *luaF_newclosure (lua_State *L, int nelems); void luaF_freeproto (lua_State *L, Proto *f); void luaF_freeclosure (lua_State *L, Closure *c); diff --git a/lgc.c b/lgc.c index 9e84919f..296179a6 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.66 2000/09/19 08:42:35 roberto Exp roberto $ +** $Id: lgc.c,v 1.67 2000/09/25 14:52:10 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -254,7 +254,7 @@ static void collectstringtab (lua_State *L, int limit) { else { /* collect */ *p = next->nexthash; L->strt.nuse--; - L->nblocks -= gcsizestring(L, next->u.s.len); + L->nblocks -= sizestring(next->u.s.len); luaM_free(L, next); } } @@ -343,7 +343,9 @@ long lua_collectgarbage (lua_State *L, long limit) { recovered = recovered - L->nblocks; L->GCthreshold = (limit == 0) ? 2*L->nblocks : L->nblocks+limit; if (L->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */ - L->Mbuffsize /= 2; /* still larger than MINBUFFER */ + size_t diff = L->Mbuffsize/2; + L->Mbuffsize -= diff; /* still larger than MINBUFFER */ + L->nblocks -= diff*sizeof(char); luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, char); } callgcTM(L, &luaO_nilobject); diff --git a/llimits.h b/llimits.h index 4c66c7b5..80acda78 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.13 2000/08/28 17:57:04 roberto Exp roberto $ +** $Id: llimits.h,v 1.14 2000/08/29 14:48:16 roberto Exp roberto $ ** Limits, basic types, and some other "installation-dependent" definitions ** See Copyright Notice in lua.h */ @@ -57,13 +57,6 @@ typedef unsigned long lint32; /* unsigned int with at least 32 bits */ #define IntPoint(p) (((unsigned long)(p)) >> 3) -/* -** number of `blocks' for garbage collection: each reference to other -** objects count 1, and each 32 bytes of `raw' memory count 1; we add -** 2 to the total as a minimum (and also to count the overhead of malloc) -*/ -#define numblocks(L, o,b) ((o)+((b)>>5)+2) - #define MINPOWER2 4 /* minimum size for "growing" vectors */ @@ -77,7 +70,7 @@ typedef unsigned long lint32; /* unsigned int with at least 32 bits */ /* ** type for virtual-machine instructions -** must be an unsigned with 4 bytes (see details in lopcodes.h) +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) ** For a very small machine, you may change that to 2 bytes (and adjust ** the following limits accordingly) */ diff --git a/lobject.c b/lobject.c index c58d4bc2..2256e953 100644 --- a/lobject.c +++ b/lobject.c @@ -1,5 +1,5 @@ /* -** $Id: lobject.c,v 1.47 2000/09/11 20:29:27 roberto Exp roberto $ +** $Id: lobject.c,v 1.48 2000/09/12 13:47:39 roberto Exp roberto $ ** Some generic functions over Lua objects ** See Copyright Notice in lua.h */ @@ -18,7 +18,7 @@ /* -** you can use the fact that the 3rd letter or each name is always different +** you can use the fact that the 3rd letter of each name is always different ** (e-m-r-b-n-l) to compare and switch these strings */ const char *const luaO_typenames[] = { /* ORDER LUA_T */ @@ -61,6 +61,7 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) { char *luaO_openspace (lua_State *L, size_t n) { if (n > L->Mbuffsize) { luaM_reallocvector(L, L->Mbuffer, n, char); + L->nblocks += (n - L->Mbuffsize)*sizeof(char); L->Mbuffsize = n; } return L->Mbuffer; @@ -127,10 +128,10 @@ int luaO_str2d (const char *s, Number *result) { /* LUA_NUMBER */ } -/* this function needs to handle only '%d' and '%.XXXs' formats */ +/* this function needs to handle only '%d' and '%.XXs' formats */ void luaO_verror (lua_State *L, const char *fmt, ...) { - char buff[500]; va_list argp; + char buff[600]; /* to hold formated message */ va_start(argp, fmt); vsprintf(buff, fmt, argp); va_end(argp); diff --git a/lobject.h b/lobject.h index c455bc3d..bd8a5a73 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.75 2000/09/11 17:38:42 roberto Exp roberto $ +** $Id: lobject.h,v 1.76 2000/09/11 20:29:27 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -116,14 +116,16 @@ typedef struct Proto { int nkstr; /* size of `kstr' */ struct Proto **kproto; /* functions defined inside the function */ int nkproto; /* size of `kproto' */ - Instruction *code; /* ends with opcode ENDCODE */ - int numparams; - int is_vararg; - int maxstacksize; + Instruction *code; + int ncode; /* size of `code'; when 0 means an incomplete `Proto' */ + short numparams; + short is_vararg; + short maxstacksize; + short marked; struct Proto *next; - int marked; /* debug information */ int *lineinfo; /* map from opcodes to source lines */ + int nlineinfo; /* size of `lineinfo' */ int nlocvars; struct LocVar *locvars; /* information about local variables */ int lineDefined; diff --git a/lparser.c b/lparser.c index 9404c5bc..e85b4cde 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.112 2000/09/20 17:57:08 roberto Exp roberto $ +** $Id: lparser.c,v 1.113 2000/09/27 17:41:58 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -315,7 +315,6 @@ static void open_func (LexState *ls, FuncState *fs) { f->source = ls->source; fs->pc = 0; fs->lasttarget = 0; - fs->nlineinfo = 0; fs->lastline = 0; fs->jlt = NO_JUMP; f->code = NULL; @@ -337,8 +336,9 @@ static void close_func (LexState *ls) { luaM_reallocvector(L, f->kproto, f->nkproto, Proto *); removelocalvars(ls, fs->nactloc); luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar); - luaM_reallocvector(L, f->lineinfo, fs->nlineinfo+1, int); - f->lineinfo[fs->nlineinfo] = MAX_INT; /* end flag */ + luaM_reallocvector(L, f->lineinfo, f->nlineinfo+1, int); + f->lineinfo[f->nlineinfo] = MAX_INT; /* end flag */ + luaF_protook(L, f, fs->pc); /* proto is ok now */ ls->fs = fs->prev; LUA_ASSERT(fs->bl == NULL, "wrong list end"); } diff --git a/lparser.h b/lparser.h index 24678a86..62444934 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.23 2000/08/22 17:44:17 roberto Exp roberto $ +** $Id: lparser.h,v 1.24 2000/08/30 18:50:18 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -48,7 +48,6 @@ typedef struct FuncState { int nactloc; /* number of active local variables */ int nupvalues; /* number of upvalues */ int lastline; /* line where last `lineinfo' was generated */ - int nlineinfo; /* index of next `lineinfo' to be generated */ struct Breaklabel *bl; /* chain of breakable blocks */ expdesc upvalues[MAXUPVALUES]; /* upvalues */ int actloc[MAXLOCALS]; /* local-variable stack (indices to locvars) */ diff --git a/lstate.c b/lstate.c index 71671785..874b35bd 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.40 2000/09/21 14:41:25 roberto Exp roberto $ +** $Id: lstate.c,v 1.41 2000/09/25 16:22:42 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -78,7 +78,7 @@ lua_State *lua_open (int stacksize) { L->refArray = NULL; L->refSize = 0; L->refFree = NONEXT; - L->nblocks = 0; + L->nblocks = sizeof(lua_State); L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */ L->callhook = NULL; L->linehook = NULL; @@ -100,11 +100,16 @@ void lua_close (lua_State *L) { LUA_ASSERT(L->rootcl == NULL, "list should be empty"); LUA_ASSERT(L->roottable == NULL, "list should be empty"); luaS_freeall(L); + if (L->stack) + L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject); luaM_free(L, L->stack); + L->nblocks -= (L->last_tag+1)*sizeof(struct IM); luaM_free(L, L->IMtable); + L->nblocks -= (L->refSize)*sizeof(struct Ref); luaM_free(L, L->refArray); + L->nblocks -= (L->Mbuffsize)*sizeof(char); luaM_free(L, L->Mbuffer); - LUA_ASSERT(L->nblocks == 0, "wrong count for nblocks"); + LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks"); luaM_free(L, L); LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!"); LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!"); diff --git a/lstate.h b/lstate.h index 8d54e932..9c31349a 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.38 2000/09/11 17:38:42 roberto Exp roberto $ +** $Id: lstate.h,v 1.39 2000/09/25 16:22:42 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -65,7 +65,7 @@ struct lua_State { int refSize; /* size of refArray */ int refFree; /* list of free positions in refArray */ unsigned long GCthreshold; - unsigned long nblocks; /* number of `blocks' currently allocated */ + unsigned long nblocks; /* number of `bytes' currently allocated */ lua_Hook callhook; lua_Hook linehook; int allowhooks; diff --git a/lstring.c b/lstring.c index 1b0551c3..02dd54c1 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.41 2000/08/04 19:38:35 roberto Exp roberto $ +** $Id: lstring.c,v 1.42 2000/08/09 19:16:57 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -19,6 +19,7 @@ void luaS_init (lua_State *L) { L->strt.hash = luaM_newvector(L, 1, TString *); L->udt.hash = luaM_newvector(L, 1, TString *); + L->nblocks += 2*sizeof(TString *); L->strt.size = L->udt.size = 1; L->strt.nuse = L->udt.nuse = 0; L->strt.hash[0] = L->udt.hash[0] = NULL; @@ -27,6 +28,7 @@ void luaS_init (lua_State *L) { void luaS_freeall (lua_State *L) { LUA_ASSERT(L->strt.nuse==0, "non-empty string table"); + L->nblocks -= (L->strt.size + L->udt.size)*sizeof(TString *); luaM_free(L, L->strt.hash); LUA_ASSERT(L->udt.nuse==0, "non-empty udata table"); luaM_free(L, L->udt.hash); @@ -61,6 +63,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) { } } luaM_free(L, tb->hash); + L->nblocks += (newsize - tb->size)*sizeof(TString *); tb->size = newsize; tb->hash = newhash; } @@ -85,7 +88,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { return ts; } /* not found */ - ts = (TString *)luaM_malloc(L, sizeof(TString)+(lint32)l*sizeof(char)); + ts = (TString *)luaM_malloc(L, sizestring(l)); ts->marked = 0; ts->nexthash = NULL; ts->u.s.len = l; @@ -93,7 +96,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { ts->u.s.constindex = 0; memcpy(ts->str, str, l); ts->str[l] = 0; /* ending 0 */ - L->nblocks += gcsizestring(L, l); + L->nblocks += sizestring(l); newentry(L, &L->strt, ts, h1); /* insert it on table */ return ts; } diff --git a/lstring.h b/lstring.h index 2b853a0f..c04ef12a 100644 --- a/lstring.h +++ b/lstring.h @@ -1,5 +1,5 @@ /* -** $Id: lstring.h,v 1.20 2000/05/10 16:33:20 roberto Exp roberto $ +** $Id: lstring.h,v 1.21 2000/05/24 13:54:49 roberto Exp roberto $ ** String table (keep all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -20,8 +20,8 @@ #define RESERVEDMARK 3 -#define gcsizestring(L, l) numblocks(L, 0, sizeof(TString)+l) -#define gcsizeudata gcsizestring(L, 0) +#define sizestring(l) (sizeof(TString)+(lint32)(l)*sizeof(char)) +#define gcsizeudata (sizeof(TString)) void luaS_init (lua_State *L); diff --git a/ltable.c b/ltable.c index 2f7ef3dc..7a732e53 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.54 2000/08/31 14:08:27 roberto Exp roberto $ +** $Id: ltable.c,v 1.55 2000/09/11 20:29:27 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -27,7 +27,7 @@ #include "ltable.h" -#define gcsize(L, n) numblocks(L, n*2, sizeof(Hash)) +#define gcsize(L, n) (sizeof(Hash)+(n)*sizeof(Node)) diff --git a/ltests.c b/ltests.c index 85bfaad8..f84383ce 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 1.43 2000/09/25 14:48:42 roberto Exp roberto $ +** $Id: ltests.c,v 1.44 2000/09/25 16:22:42 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -166,7 +166,8 @@ static int mem_query (lua_State *L) { lua_pushnumber(L, memdebug_total); lua_pushnumber(L, memdebug_numblocks); lua_pushnumber(L, memdebug_maxmem); - return 3; +lua_pushnumber(L, L->nblocks); + return 4; } else { memdebug_memlimit = luaL_check_int(L, 1); diff --git a/ltm.c b/ltm.c index ca4ea88d..fd854d66 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.48 2000/09/11 19:45:27 roberto Exp roberto $ +** $Id: ltm.c,v 1.49 2000/09/11 20:29:27 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -77,6 +77,7 @@ static void init_entry (lua_State *L, int tag) { void luaT_init (lua_State *L) { int t; luaM_growvector(L, L->IMtable, 0, NUM_TAGS, struct IM, "", MAX_INT); + L->nblocks += NUM_TAGS*sizeof(struct IM); L->last_tag = NUM_TAGS-1; for (t=0; t<=L->last_tag; t++) init_entry(L, t); @@ -86,6 +87,7 @@ void luaT_init (lua_State *L) { int lua_newtag (lua_State *L) { luaM_growvector(L, L->IMtable, L->last_tag, 1, struct IM, "tag table overflow", MAX_INT); + L->nblocks += sizeof(struct IM); L->last_tag++; init_entry(L, L->last_tag); return L->last_tag;