From 8c49e198654567f770a7d5081b886a7c35201d81 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 26 Dec 2000 16:46:09 -0200 Subject: explicit control of size for growing vectors --- lapi.c | 12 ++++++------ lcode.c | 19 +++++++++++-------- ldebug.c | 4 ++-- lgc.c | 10 +++++----- lmem.c | 25 +++++++++++++++---------- lmem.h | 12 ++++++------ lparser.c | 31 +++++++++++++++++++------------ lparser.h | 8 +++++++- lstate.c | 12 +++++++----- lstate.h | 8 +++++--- ltm.c | 20 ++++++++++---------- ltm.h | 4 ++-- 12 files changed, 95 insertions(+), 70 deletions(-) diff --git a/lapi.c b/lapi.c index bb7516e9..b1b7d0ff 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.111 2000/11/24 17:39:56 roberto Exp roberto $ +** $Id: lapi.c,v 1.112 2000/12/04 18:33:40 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -289,7 +289,7 @@ LUA_API void lua_getglobals (lua_State *L) { LUA_API int lua_getref (lua_State *L, int ref) { if (ref == LUA_REFNIL) ttype(L->top) = LUA_TNIL; - else if (0 <= ref && ref < L->refSize && + else if (0 <= ref && ref < L->nref && (L->refArray[ref].st == LOCK || L->refArray[ref].st == HOLD)) *L->top = L->refArray[ref].o; else @@ -360,10 +360,10 @@ LUA_API int lua_ref (lua_State *L, int lock) { L->refFree = L->refArray[ref].st; } else { /* no more free places */ - luaM_growvector(L, L->refArray, L->refSize, 1, struct Ref, - "reference table overflow", MAX_INT); + luaM_growvector(L, L->refArray, L->nref, L->sizeref, struct Ref, + MAX_INT, "reference table overflow"); L->nblocks += sizeof(struct Ref); - ref = L->refSize++; + ref = L->nref++; } L->refArray[ref].o = *(L->top-1); L->refArray[ref].st = lock ? LOCK : HOLD; @@ -430,7 +430,7 @@ LUA_API void lua_settag (lua_State *L, int tag) { LUA_API void lua_unref (lua_State *L, int ref) { if (ref >= 0) { - LUA_ASSERT(ref < L->refSize && L->refArray[ref].st < 0, "invalid ref"); + LUA_ASSERT(ref < L->nref && L->refArray[ref].st < 0, "invalid ref"); L->refArray[ref].st = L->refFree; L->refFree = ref; } diff --git a/lcode.c b/lcode.c index 306661c3..685ce748 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.52 2000/11/30 18:50:47 roberto Exp roberto $ +** $Id: lcode.c,v 1.53 2000/12/04 18:33:40 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -107,8 +107,8 @@ static int number_constant (FuncState *fs, lua_Number r) { while (--c >= lim) if (f->knum[c] == r) return c; /* not found; create a new entry */ - luaM_growvector(fs->L, f->knum, f->nknum, 1, lua_Number, - "constant table overflow", MAXARG_U); + luaM_growvector(fs->L, f->knum, f->nknum, fs->sizeknum, lua_Number, + MAXARG_U, "constant table overflow"); c = f->nknum++; f->knum[c] = r; return c; @@ -423,10 +423,13 @@ static void codelineinfo (FuncState *fs) { Proto *f = fs->f; LexState *ls = fs->ls; if (ls->lastline > fs->lastline) { - luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, 2, int, - "line info overflow", MAX_INT); - if (ls->lastline > fs->lastline+1) + if (ls->lastline > fs->lastline+1) { + luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int, + MAX_INT, "line info overflow"); f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1)); + } + luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int, + MAX_INT, "line info overflow"); f->lineinfo[f->nlineinfo++] = fs->pc; fs->lastline = ls->lastline; } @@ -640,8 +643,8 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { } codelineinfo(fs); /* put new instruction in code array */ - luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, - "code size overflow", MAX_INT); + luaM_growvector(fs->L, fs->f->code, fs->pc, fs->sizecode, Instruction, + MAX_INT, "code size overflow"); fs->f->code[fs->pc] = i; return fs->pc++; } diff --git a/ldebug.c b/ldebug.c index 72344181..b3cc80d8 100644 --- a/ldebug.c +++ b/ldebug.c @@ -1,5 +1,5 @@ /* -** $Id: ldebug.c,v 1.50 2000/10/30 12:38:50 roberto Exp roberto $ +** $Id: ldebug.c,v 1.51 2000/11/30 18:50:47 roberto Exp roberto $ ** Debug Interface ** See Copyright Notice in lua.h */ @@ -210,7 +210,7 @@ static const char *travtagmethods (lua_State *L, const TObject *o) { int e; for (e=0; elast_tag; t++) + for (t=0; tntag; t++) if (clvalue(o) == luaT_gettm(L, t, e)) return luaT_eventname[e]; } diff --git a/lgc.c b/lgc.c index 6949b061..7b35ee03 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.72 2000/10/26 12:47:05 roberto Exp roberto $ +** $Id: lgc.c,v 1.73 2000/11/24 17:39:56 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -56,7 +56,7 @@ static void markstack (lua_State *L, GCState *st) { static void marklock (lua_State *L, GCState *st) { int i; - for (i=0; irefSize; i++) { + for (i=0; inref; i++) { if (L->refArray[i].st == LOCK) markobject(st, &L->refArray[i].o); } @@ -77,7 +77,7 @@ static void marktagmethods (lua_State *L, GCState *st) { int e; for (e=0; elast_tag; t++) { + for (t=0; tntag; t++) { Closure *cl = luaT_gettm(L, t, e); if (cl) markclosure(st, cl); } @@ -162,7 +162,7 @@ static int hasmark (const TObject *o) { #define VALIDLINK(L, st,n) (NONEXT <= (st) && (st) < (n)) static void invalidaterefs (lua_State *L) { - int n = L->refSize; + int n = L->nref; int i; for (i=0; irefArray[i]; @@ -314,7 +314,7 @@ static void callgcTMudata (lua_State *L) { TObject o; ttype(&o) = LUA_TUSERDATA; L->GCthreshold = 2*L->nblocks; /* avoid GC during tag methods */ - for (tag=L->last_tag; tag>=0; tag--) { /* for each tag (in reverse order) */ + for (tag=L->ntag-1; tag>=0; tag--) { /* for each tag (in reverse order) */ TString *udata; while ((udata = L->TMtable[tag].collected) != NULL) { L->TMtable[tag].collected = udata->nexthash; /* remove it from list */ diff --git a/lmem.c b/lmem.c index 3a219f27..830f6f1d 100644 --- a/lmem.c +++ b/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.39 2000/10/30 16:29:59 roberto Exp roberto $ +** $Id: lmem.c,v 1.40 2000/11/24 17:39:56 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -116,15 +116,20 @@ static void *debug_realloc (void *block, size_t size) { #endif -void *luaM_growaux (lua_State *L, void *block, size_t nelems, - int inc, size_t size, const char *errormsg, size_t limit) { - size_t newn = nelems+inc; - if (nelems >= limit-inc) lua_error(L, errormsg); - if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */ - (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */ - return block; /* do not need to reallocate */ - else /* it crossed a power-of-2 boundary; grow to next power */ - return luaM_realloc(L, block, luaO_power2(newn)*size); +void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, + int limit, const char *errormsg) { + void *newblock; + int newsize = (*size)*2; + if (newsize < MINPOWER2) + newsize = MINPOWER2; /* minimum size */ + else if (*size >= limit/2) { /* cannot double it? */ + if (*size < limit - MINPOWER2) /* try something smaller... */ + newsize = limit; /* still have at least MINPOWER2 free places */ + else lua_error(L, errormsg); + } + newblock = luaM_realloc(L, block, (luint32)newsize*(luint32)size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; } diff --git a/lmem.h b/lmem.h index 8147de5c..c2ee8213 100644 --- a/lmem.h +++ b/lmem.h @@ -1,5 +1,5 @@ /* -** $Id: lmem.h,v 1.16 2000/10/30 16:29:59 roberto Exp roberto $ +** $Id: lmem.h,v 1.17 2000/11/24 17:39:56 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -14,17 +14,17 @@ #include "lua.h" void *luaM_realloc (lua_State *L, void *oldblock, luint32 size); -void *luaM_growaux (lua_State *L, void *block, size_t nelems, - int inc, size_t size, const char *errormsg, - size_t limit); +void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem, + int limit, const char *errormsg); #define luaM_free(L, b) luaM_realloc(L, (b), 0) #define luaM_malloc(L, t) luaM_realloc(L, NULL, (t)) #define luaM_new(L, t) ((t *)luaM_malloc(L, sizeof(t))) #define luaM_newvector(L, n,t) ((t *)luaM_malloc(L, (n)*(luint32)sizeof(t))) -#define luaM_growvector(L, v,nelems,inc,t,e,l) \ - ((v)=(t *)luaM_growaux(L, v,nelems,inc,sizeof(t),e,l)) +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + if (((nelems)+1) > (size)) \ + ((v)=(t *)luaM_growaux(L,v,&(size),sizeof(t),limit,e)) #define luaM_reallocvector(L, v,n,t) \ ((v)=(t *)luaM_realloc(L, v,(n)*(luint32)sizeof(t))) diff --git a/lparser.c b/lparser.c index d5df16d6..f4e4c551 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.118 2000/11/30 18:50:47 roberto Exp roberto $ +** $Id: lparser.c,v 1.119 2000/12/04 18:33:40 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -121,8 +121,8 @@ static int string_constant (FuncState *fs, TString *s) { Proto *f = fs->f; int c = s->u.s.constindex; if (c >= f->nkstr || f->kstr[c] != s) { - luaM_growvector(fs->L, f->kstr, f->nkstr, 1, TString *, - "constant table overflow", MAXARG_U); + luaM_growvector(fs->L, f->kstr, f->nkstr, fs->sizekstr, TString *, + MAXARG_U, "constant table overflow"); c = f->nkstr++; f->kstr[c] = s; s->u.s.constindex = c; /* hint for next time */ @@ -152,7 +152,8 @@ static int checkname (LexState *ls) { static int luaI_registerlocalvar (LexState *ls, TString *varname) { Proto *f = ls->fs->f; - luaM_growvector(ls->L, f->locvars, f->nlocvars, 1, LocVar, "", MAX_INT); + luaM_growvector(ls->L, f->locvars, f->nlocvars, ls->fs->sizelocvars, + LocVar, MAX_INT, ""); f->locvars[f->nlocvars].varname = varname; return f->nlocvars++; } @@ -294,8 +295,8 @@ static void pushclosure (LexState *ls, FuncState *func) { int i; for (i=0; inupvalues; i++) luaK_tostack(ls, &func->upvalues[i], 1); - luaM_growvector(ls->L, f->kproto, f->nkproto, 1, Proto *, - "constant table overflow", MAXARG_A); + luaM_growvector(ls->L, f->kproto, f->nkproto, fs->sizekproto, Proto *, + MAXARG_A, "constant table overflow"); f->kproto[f->nkproto++] = func->f; luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues); } @@ -303,21 +304,27 @@ static void pushclosure (LexState *ls, FuncState *func) { static void open_func (LexState *ls, FuncState *fs) { Proto *f = luaF_newproto(ls->L); + fs->f = f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; fs->L = ls->L; ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jlt = NO_JUMP; fs->stacklevel = 0; + fs->sizekstr = 0; + fs->sizekproto = 0; + fs->sizeknum = 0; + fs->sizelineinfo = 0; + fs->sizecode = 0; + fs->sizelocvars = 0; fs->nactloc = 0; fs->nupvalues = 0; - fs->bl = NULL; - fs->f = f; - f->source = ls->source; - fs->pc = 0; - fs->lasttarget = 0; fs->lastline = 0; - fs->jlt = NO_JUMP; + fs->bl = NULL; f->code = NULL; + f->source = ls->source; f->maxstacksize = 0; f->numparams = 0; /* default for main chunk */ f->is_vararg = 0; /* default for main chunk */ diff --git a/lparser.h b/lparser.h index 7e8bd2d1..9c34a861 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.26 2000/10/09 13:47:46 roberto Exp roberto $ +** $Id: lparser.h,v 1.27 2000/11/30 18:50:47 roberto Exp roberto $ ** LL(1) Parser and code generator for Lua ** See Copyright Notice in lua.h */ @@ -45,6 +45,12 @@ typedef struct FuncState { int lasttarget; /* `pc' of last `jump target' */ int jlt; /* list of jumps to `lasttarget' */ int stacklevel; /* number of values on activation register */ + int sizekstr; /* size of array `kstr' */ + int sizekproto; /* size of array `kproto' */ + int sizeknum; /* size of array `knum' */ + int sizelineinfo; /* size of array `lineinfo' */ + int sizecode; /* size of array `code' */ + int sizelocvars; /* size of array `locvars' */ int nactloc; /* number of active local variables */ int nupvalues; /* number of upvalues */ int lastline; /* line where last `lineinfo' was generated */ diff --git a/lstate.c b/lstate.c index b62cdd98..90ee5cb3 100644 --- a/lstate.c +++ b/lstate.c @@ -1,5 +1,5 @@ /* -** $Id: lstate.c,v 1.47 2000/10/26 12:47:05 roberto Exp roberto $ +** $Id: lstate.c,v 1.48 2000/10/30 16:29:59 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -77,9 +77,11 @@ LUA_API lua_State *lua_open (int stacksize) { L->rootcl = NULL; L->roottable = NULL; L->TMtable = NULL; - L->last_tag = -1; + L->sizeTM = 0; + L->ntag = 0; L->refArray = NULL; - L->refSize = 0; + L->nref = 0; + L->sizeref = 0; L->refFree = NONEXT; L->nblocks = sizeof(lua_State); L->GCthreshold = MAX_INT; /* to avoid GC during pre-definitions */ @@ -107,9 +109,9 @@ LUA_API void lua_close (lua_State *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 TM); + L->nblocks -= L->ntag*sizeof(struct TM); luaM_free(L, L->TMtable); - L->nblocks -= (L->refSize)*sizeof(struct Ref); + L->nblocks -= (L->nref)*sizeof(struct Ref); luaM_free(L, L->refArray); L->nblocks -= (L->Mbuffsize)*sizeof(char); luaM_free(L, L->Mbuffer); diff --git a/lstate.h b/lstate.h index 51c6e27d..abd212ad 100644 --- a/lstate.h +++ b/lstate.h @@ -1,5 +1,5 @@ /* -** $Id: lstate.h,v 1.41 2000/10/05 13:00:17 roberto Exp roberto $ +** $Id: lstate.h,v 1.42 2000/11/24 17:39:56 roberto Exp roberto $ ** Global State ** See Copyright Notice in lua.h */ @@ -61,9 +61,11 @@ struct lua_State { stringtable udt; /* hash table for udata */ Hash *gt; /* table for globals */ struct TM *TMtable; /* table for tag methods */ - int last_tag; /* last used tag in TMtable */ + int sizeTM; /* size of TMtable */ + int ntag; /* number of tags in TMtable */ struct Ref *refArray; /* locked objects */ - int refSize; /* size of refArray */ + int nref; /* first unused element in refArray */ + int sizeref; /* size of refArray */ int refFree; /* list of free positions in refArray */ mem_int GCthreshold; mem_int nblocks; /* number of `bytes' currently allocated */ diff --git a/ltm.c b/ltm.c index ffe7a38b..852dfd13 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.56 2000/10/31 13:10:24 roberto Exp roberto $ +** $Id: ltm.c,v 1.57 2000/11/30 18:50:47 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -75,26 +75,26 @@ static void init_entry (lua_State *L, int tag) { void luaT_init (lua_State *L) { int t; - luaM_growvector(L, L->TMtable, 0, NUM_TAGS, struct TM, "", MAX_INT); + L->sizeTM = NUM_TAGS+2; + L->TMtable = luaM_newvector(L, L->sizeTM, struct TM); L->nblocks += NUM_TAGS*sizeof(struct TM); - L->last_tag = NUM_TAGS-1; - for (t=0; t<=L->last_tag; t++) + L->ntag = NUM_TAGS; + for (t=0; tntag; t++) init_entry(L, t); } LUA_API int lua_newtag (lua_State *L) { - luaM_growvector(L, L->TMtable, L->last_tag, 1, struct TM, - "tag table overflow", MAX_INT); + luaM_growvector(L, L->TMtable, L->ntag, L->sizeTM, struct TM, + MAX_INT, "tag table overflow"); L->nblocks += sizeof(struct TM); - L->last_tag++; - init_entry(L, L->last_tag); - return L->last_tag; + init_entry(L, L->ntag); + return L->ntag++; } static void checktag (lua_State *L, int tag) { - if (!(0 <= tag && tag <= L->last_tag)) + if (!(0 <= tag && tag < L->ntag)) luaO_verror(L, "%d is not a valid tag", tag); } diff --git a/ltm.h b/ltm.h index f72f9867..bb33d3ce 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 1.17 2000/10/05 12:14:08 roberto Exp roberto $ +** $Id: ltm.h,v 1.18 2000/10/05 13:00:17 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -45,7 +45,7 @@ struct TM { #define luaT_gettmbyObj(L,o,e) (luaT_gettm((L),luaT_tag(o),(e))) -#define validtag(t) (NUM_TAGS <= (t) && (t) <= L->last_tag) +#define validtag(t) (NUM_TAGS <= (t) && (t) < L->ntag) extern const char *const luaT_eventname[]; -- cgit v1.2.3-55-g6feb