2
0
Эх сурвалжийг харах

`free' gets size of the block: complete control over memory use

Roberto Ierusalimschy 24 жил өмнө
parent
commit
0183b8030c
20 өөрчлөгдсөн 207 нэмэгдсэн , 224 устгасан
  1. 1 2
      lapi.c
  2. 13 11
      lcode.c
  3. 14 12
      ldo.c
  4. 17 39
      lfunc.c
  5. 1 2
      lfunc.h
  6. 7 10
      lgc.c
  7. 43 28
      lmem.c
  8. 15 7
      lmem.h
  9. 2 3
      lobject.c
  10. 7 7
      lobject.h
  11. 30 25
      lparser.c
  12. 7 8
      lparser.h
  13. 9 14
      lstate.c
  14. 8 27
      lstring.c
  15. 14 1
      lstring.h
  16. 4 11
      ltable.c
  17. 2 2
      ltests.c
  18. 2 4
      ltm.c
  19. 8 8
      lundump.c
  20. 3 3
      lvm.c

+ 1 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lapi.c,v 1.112 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: lapi.c,v 1.113 2000/12/26 18:46:09 roberto Exp roberto $
 ** Lua API
 ** Lua API
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -362,7 +362,6 @@ LUA_API int lua_ref (lua_State *L,  int lock) {
     else {  /* no more free places */
     else {  /* no more free places */
       luaM_growvector(L, L->refArray, L->nref, L->sizeref, struct Ref,
       luaM_growvector(L, L->refArray, L->nref, L->sizeref, struct Ref,
                       MAX_INT, "reference table overflow");
                       MAX_INT, "reference table overflow");
-      L->nblocks += sizeof(struct Ref);
       ref = L->nref++;
       ref = L->nref++;
     }
     }
     L->refArray[ref].o = *(L->top-1);
     L->refArray[ref].o = *(L->top-1);

+ 13 - 11
lcode.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lcode.c,v 1.53 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: lcode.c,v 1.54 2000/12/26 18:46:09 roberto Exp roberto $
 ** Code generator for Lua
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -102,14 +102,14 @@ void luaK_kstr (LexState *ls, int c) {
 static int number_constant (FuncState *fs, lua_Number r) {
 static int number_constant (FuncState *fs, lua_Number r) {
   /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
   /* check whether `r' has appeared within the last LOOKBACKNUMS entries */
   Proto *f = fs->f;
   Proto *f = fs->f;
-  int c = f->nknum;
+  int c = fs->nknum;
   int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
   int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;
   while (--c >= lim)
   while (--c >= lim)
     if (f->knum[c] == r) return c;
     if (f->knum[c] == r) return c;
   /* not found; create a new entry */
   /* not found; create a new entry */
-  luaM_growvector(fs->L, f->knum, f->nknum, fs->sizeknum, lua_Number,
+  luaM_growvector(fs->L, f->knum, fs->nknum, f->sizeknum, lua_Number,
                   MAXARG_U, "constant table overflow");
                   MAXARG_U, "constant table overflow");
-  c = f->nknum++;
+  c = fs->nknum++;
   f->knum[c] = r;
   f->knum[c] = r;
   return c;
   return c;
 }
 }
@@ -424,13 +424,13 @@ static void codelineinfo (FuncState *fs) {
   LexState *ls = fs->ls;
   LexState *ls = fs->ls;
   if (ls->lastline > fs->lastline) {
   if (ls->lastline > fs->lastline) {
     if (ls->lastline > fs->lastline+1) {
     if (ls->lastline > fs->lastline+1) {
-      luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int,
+      luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int,
                       MAX_INT, "line info overflow");
                       MAX_INT, "line info overflow");
-      f->lineinfo[f->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
+      f->lineinfo[fs->nlineinfo++] = -(ls->lastline - (fs->lastline+1));
     }
     }
-    luaM_growvector(fs->L, f->lineinfo, f->nlineinfo, fs->sizelineinfo, int,
+    luaM_growvector(fs->L, f->lineinfo, fs->nlineinfo, f->sizelineinfo, int,
                     MAX_INT, "line info overflow");
                     MAX_INT, "line info overflow");
-    f->lineinfo[f->nlineinfo++] = fs->pc;
+    f->lineinfo[fs->nlineinfo++] = fs->pc;
     fs->lastline = ls->lastline;
     fs->lastline = ls->lastline;
   }
   }
 }
 }
@@ -447,6 +447,7 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) {
 
 
 
 
 int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
 int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
+  Proto *f;
   Instruction i = previous_instruction(fs);
   Instruction i = previous_instruction(fs);
   int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop;
   int delta = (int)luaK_opproperties[o].push - (int)luaK_opproperties[o].pop;
   int optm = 0;  /* 1 when there is an optimization */
   int optm = 0;  /* 1 when there is an optimization */
@@ -629,9 +630,10 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
       break;
       break;
     }
     }
   }
   }
+  f = fs->f;
   luaK_deltastack(fs, delta);
   luaK_deltastack(fs, delta);
   if (optm) {  /* optimize: put instruction in place of last one */
   if (optm) {  /* optimize: put instruction in place of last one */
-      fs->f->code[fs->pc-1] = i;  /* change previous instruction */
+      f->code[fs->pc-1] = i;  /* change previous instruction */
       return fs->pc-1;  /* do not generate new instruction */
       return fs->pc-1;  /* do not generate new instruction */
   }
   }
   /* else build new instruction */
   /* else build new instruction */
@@ -643,9 +645,9 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) {
   }
   }
   codelineinfo(fs);
   codelineinfo(fs);
   /* put new instruction in code array */
   /* put new instruction in code array */
-  luaM_growvector(fs->L, fs->f->code, fs->pc, fs->sizecode, Instruction,
+  luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
                   MAX_INT, "code size overflow");
                   MAX_INT, "code size overflow");
-  fs->f->code[fs->pc] = i;
+  f->code[fs->pc] = i;
   return fs->pc++;
   return fs->pc++;
 }
 }
 
 

+ 14 - 12
ldo.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ldo.c,v 1.109 2000/10/30 12:38:50 roberto Exp roberto $
+** $Id: ldo.c,v 1.110 2000/11/24 17:39:56 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -28,38 +28,40 @@
 
 
 
 
 /* space to handle stack overflow errors */
 /* space to handle stack overflow errors */
-#define EXTRA_STACK	(2*LUA_MINSTACK)
+#define EXTRA_STACK   (2*LUA_MINSTACK)
+
+
+static void restore_stack_limit (lua_State *L) {
+  StkId limit = L->stack+(L->stacksize-EXTRA_STACK)-1;
+  if (L->top < limit)
+    L->stack_last = limit;
+}
 
 
 
 
 void luaD_init (lua_State *L, int stacksize) {
 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);
+  stacksize += EXTRA_STACK;
+  L->stack = luaM_newvector(L, stacksize, TObject);
   L->stacksize = stacksize;
   L->stacksize = stacksize;
   L->Cbase = L->top = L->stack;
   L->Cbase = L->top = L->stack;
+  restore_stack_limit(L);
 }
 }
 
 
 
 
 void luaD_checkstack (lua_State *L, int n) {
 void luaD_checkstack (lua_State *L, int n) {
   if (L->stack_last - L->top <= n) {  /* stack overflow? */
   if (L->stack_last - L->top <= n) {  /* stack overflow? */
-    if (L->stack_last-L->stack > (L->stacksize-1)) {
+    if (L->stack_last == L->stack+L->stacksize-1) {
       /* overflow while handling overflow */
       /* overflow while handling overflow */
       luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
       luaD_breakrun(L, LUA_ERRERR);  /* break run without error message */
     }
     }
     else {
     else {
       L->stack_last += EXTRA_STACK;  /* to be used by error message */
       L->stack_last += EXTRA_STACK;  /* to be used by error message */
+      LUA_ASSERT(L->stack_last == L->stack+L->stacksize-1, "wrong stack limit");
       lua_error(L, "stack overflow");
       lua_error(L, "stack overflow");
     }
     }
   }
   }
 }
 }
 
 
 
 
-static void restore_stack_limit (lua_State *L) {
-  if (L->top - L->stack < L->stacksize - 1)
-    L->stack_last = L->stack + (L->stacksize-1);
-}
-
-
 /*
 /*
 ** Adjust stack. Set top to base+extra, pushing NILs if needed.
 ** Adjust stack. Set top to base+extra, pushing NILs if needed.
 ** (we cannot add base+extra unless we are sure it fits in the stack;
 ** (we cannot add base+extra unless we are sure it fits in the stack;

+ 17 - 39
lfunc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lfunc.c,v 1.34 2000/10/30 12:20:29 roberto Exp roberto $
+** $Id: lfunc.c,v 1.35 2000/12/04 18:33:40 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -18,13 +18,11 @@
 
 
 
 
 Closure *luaF_newclosure (lua_State *L, int nelems) {
 Closure *luaF_newclosure (lua_State *L, int nelems) {
-  int size = sizeclosure(nelems);
-  Closure *c = (Closure *)luaM_malloc(L, size);
+  Closure *c = (Closure *)luaM_malloc(L, sizeclosure(nelems));
   c->next = L->rootcl;
   c->next = L->rootcl;
   L->rootcl = c;
   L->rootcl = c;
   c->mark = c;
   c->mark = c;
   c->nupvalues = nelems;
   c->nupvalues = nelems;
-  L->nblocks += size;
   return c;
   return c;
 }
 }
 
 
@@ -32,20 +30,20 @@ Closure *luaF_newclosure (lua_State *L, int nelems) {
 Proto *luaF_newproto (lua_State *L) {
 Proto *luaF_newproto (lua_State *L) {
   Proto *f = luaM_new(L, Proto);
   Proto *f = luaM_new(L, Proto);
   f->knum = NULL;
   f->knum = NULL;
-  f->nknum = 0;
+  f->sizeknum = 0;
   f->kstr = NULL;
   f->kstr = NULL;
-  f->nkstr = 0;
+  f->sizekstr = 0;
   f->kproto = NULL;
   f->kproto = NULL;
-  f->nkproto = 0;
+  f->sizekproto = 0;
   f->code = NULL;
   f->code = NULL;
-  f->ncode = 0;
+  f->sizecode = 0;
   f->numparams = 0;
   f->numparams = 0;
   f->is_vararg = 0;
   f->is_vararg = 0;
   f->maxstacksize = 0;
   f->maxstacksize = 0;
   f->marked = 0;
   f->marked = 0;
   f->lineinfo = NULL;
   f->lineinfo = NULL;
-  f->nlineinfo = 0;
-  f->nlocvars = 0;
+  f->sizelocvars = 0;
+  f->sizelineinfo = 0;
   f->locvars = NULL;
   f->locvars = NULL;
   f->lineDefined = 0;
   f->lineDefined = 0;
   f->source = NULL;
   f->source = NULL;
@@ -55,39 +53,19 @@ Proto *luaF_newproto (lua_State *L) {
 }
 }
 
 
 
 
-static size_t protosize (Proto *f) {
-  return sizeof(Proto)
-       + f->nknum*sizeof(lua_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) {
 void luaF_freeproto (lua_State *L, Proto *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);
-  luaM_free(L, f->knum);
-  luaM_free(L, f->kproto);
-  luaM_free(L, f->lineinfo);
-  luaM_free(L, f);
+  luaM_freearray(L, f->code, f->sizecode, Instruction);
+  luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
+  luaM_freearray(L, f->kstr, f->sizekstr, TString *);
+  luaM_freearray(L, f->knum, f->sizeknum, lua_Number);
+  luaM_freearray(L, f->kproto, f->sizekproto, Proto *);
+  luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
+  luaM_freelem(L, f, Proto);
 }
 }
 
 
 
 
 void luaF_freeclosure (lua_State *L, Closure *c) {
 void luaF_freeclosure (lua_State *L, Closure *c) {
-  L->nblocks -= sizeclosure(c->nupvalues);
-  luaM_free(L, c);
+  luaM_free(L, c, sizeclosure(c->nupvalues));
 }
 }
 
 
 
 
@@ -97,7 +75,7 @@ void luaF_freeclosure (lua_State *L, Closure *c) {
 */
 */
 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
 const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
   int i;
   int i;
-  for (i = 0; i<f->nlocvars && f->locvars[i].startpc <= pc; i++) {
+  for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
     if (pc < f->locvars[i].endpc) {  /* is variable active? */
     if (pc < f->locvars[i].endpc) {  /* is variable active? */
       local_number--;
       local_number--;
       if (local_number == 0)
       if (local_number == 0)

+ 1 - 2
lfunc.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lfunc.h,v 1.12 2000/06/26 19:28:31 roberto Exp roberto $
+** $Id: lfunc.h,v 1.13 2000/09/29 12:42:13 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -13,7 +13,6 @@
 
 
 
 
 Proto *luaF_newproto (lua_State *L);
 Proto *luaF_newproto (lua_State *L);
-void luaF_protook (lua_State *L, Proto *f, int pc);
 Closure *luaF_newclosure (lua_State *L, int nelems);
 Closure *luaF_newclosure (lua_State *L, int nelems);
 void luaF_freeproto (lua_State *L, Proto *f);
 void luaF_freeproto (lua_State *L, Proto *f);
 void luaF_freeclosure (lua_State *L, Closure *c);
 void luaF_freeclosure (lua_State *L, Closure *c);

+ 7 - 10
lgc.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lgc.c,v 1.73 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lgc.c,v 1.74 2000/12/26 18:46:09 roberto Exp roberto $
 ** Garbage Collector
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -37,11 +37,11 @@ static void protomark (Proto *f) {
     int i;
     int i;
     f->marked = 1;
     f->marked = 1;
     strmark(f->source);
     strmark(f->source);
-    for (i=0; i<f->nkstr; i++)
+    for (i=0; i<f->sizekstr; i++)
       strmark(f->kstr[i]);
       strmark(f->kstr[i]);
-    for (i=0; i<f->nkproto; i++)
+    for (i=0; i<f->sizekproto; i++)
       protomark(f->kproto[i]);
       protomark(f->kproto[i]);
-    for (i=0; i<f->nlocvars; i++)  /* mark local-variable names */
+    for (i=0; i<f->sizelocvars; i++)  /* mark local-variable names */
       strmark(f->locvars[i].varname);
       strmark(f->locvars[i].varname);
   }
   }
 }
 }
@@ -248,8 +248,7 @@ static void collectstrings (lua_State *L, int all) {
       else {  /* collect */
       else {  /* collect */
         *p = next->nexthash;
         *p = next->nexthash;
         L->strt.nuse--;
         L->strt.nuse--;
-        L->nblocks -= sizestring(next->len);
-        luaM_free(L, next);
+        luaM_free(L, next, sizestring(next->len));
       }
       }
     }
     }
   }
   }
@@ -273,7 +272,6 @@ static void collectudata (lua_State *L, int all) {
         *p = next->nexthash;
         *p = next->nexthash;
         next->nexthash = L->TMtable[tag].collected;  /* chain udata */
         next->nexthash = L->TMtable[tag].collected;  /* chain udata */
         L->TMtable[tag].collected = next;
         L->TMtable[tag].collected = next;
-        L->nblocks -= sizestring(next->len);
         L->udt.nuse--;
         L->udt.nuse--;
       }
       }
     }
     }
@@ -286,9 +284,8 @@ static void collectudata (lua_State *L, int all) {
 static void checkMbuffer (lua_State *L) {
 static void checkMbuffer (lua_State *L) {
   if (L->Mbuffsize > MINBUFFER*2) {  /* is buffer too big? */
   if (L->Mbuffsize > MINBUFFER*2) {  /* is buffer too big? */
     size_t newsize = L->Mbuffsize/2;  /* still larger than MINBUFFER */
     size_t newsize = L->Mbuffsize/2;  /* still larger than MINBUFFER */
-    L->nblocks -= (L->Mbuffsize - newsize)*sizeof(char);
+    luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, newsize, char);
     L->Mbuffsize = newsize;
     L->Mbuffsize = newsize;
-    luaM_reallocvector(L, L->Mbuffer, newsize, char);
   }
   }
 }
 }
 
 
@@ -320,7 +317,7 @@ static void callgcTMudata (lua_State *L) {
       L->TMtable[tag].collected = udata->nexthash;  /* remove it from list */
       L->TMtable[tag].collected = udata->nexthash;  /* remove it from list */
       tsvalue(&o) = udata;
       tsvalue(&o) = udata;
       callgcTM(L, &o);
       callgcTM(L, &o);
-      luaM_free(L, udata);
+      luaM_free(L, udata, sizeudata(udata->len));
     }
     }
   }
   }
 }
 }

+ 43 - 28
lmem.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lmem.c,v 1.40 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lmem.c,v 1.41 2000/12/26 18:46:09 roberto Exp roberto $
 ** Interface to Memory Manager
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -29,15 +29,14 @@
 #include <limits.h>
 #include <limits.h>
 #include <string.h>
 #include <string.h>
 
 
-#define realloc(b, s)	debug_realloc(b, s)
-#define malloc(b)	debug_realloc(NULL, b)
-#define free(b)		debug_realloc(b, 0)
+#define basicrealloc(b, os, s)	debug_realloc(b, os, s)
+#define basicfree(b, s)		debug_realloc(b, s, 0)
 
 
 
 
 /* ensures maximum alignment for HEADER */
 /* ensures maximum alignment for HEADER */
 #define HEADER	(sizeof(union L_Umaxalign))
 #define HEADER	(sizeof(union L_Umaxalign))
 
 
-#define MARKSIZE	16
+#define MARKSIZE	32
 #define MARK		0x55  /* 01010101 (a nice pattern) */
 #define MARK		0x55  /* 01010101 (a nice pattern) */
 
 
 
 
@@ -55,8 +54,6 @@ static void *checkblock (void *block) {
   int i;
   int i;
   for (i=0;i<MARKSIZE;i++)
   for (i=0;i<MARKSIZE;i++)
     assert(*(((char *)b)+HEADER+size+i) == MARK+i);  /* corrupted block? */
     assert(*(((char *)b)+HEADER+size+i) == MARK+i);  /* corrupted block? */
-  memdebug_numblocks--;
-  memdebug_total -= size;
   return b;
   return b;
 }
 }
 
 
@@ -66,12 +63,15 @@ static void freeblock (void *block) {
     size_t size = *blocksize(block);
     size_t size = *blocksize(block);
     block = checkblock(block);
     block = checkblock(block);
     memset(block, -1, size+HEADER+MARKSIZE);  /* erase block */
     memset(block, -1, size+HEADER+MARKSIZE);  /* erase block */
-    (free)(block);  /* free original block */
+    free(block);  /* free original block */
+    memdebug_numblocks--;
+    memdebug_total -= size;
   }
   }
 }
 }
 
 
 
 
-static void *debug_realloc (void *block, size_t size) {
+static void *debug_realloc (void *block, size_t oldsize, size_t size) {
+  assert((oldsize == 0) ? block == NULL : oldsize == *blocksize(block));
   if (size == 0) {
   if (size == 0) {
     freeblock(block);
     freeblock(block);
     return NULL;
     return NULL;
@@ -79,19 +79,22 @@ static void *debug_realloc (void *block, size_t size) {
   else if (memdebug_total+size > memdebug_memlimit)
   else if (memdebug_total+size > memdebug_memlimit)
     return NULL;  /* to test memory allocation errors */
     return NULL;  /* to test memory allocation errors */
   else {
   else {
-    size_t realsize = HEADER+size+MARKSIZE;
-    char *newblock = (char *)(malloc)(realsize);  /* alloc a new block */
+    char *newblock;
     int i;
     int i;
+    size_t realsize = HEADER+size+MARKSIZE;
     if (realsize < size) return NULL;  /* overflow! */
     if (realsize < size) return NULL;  /* overflow! */
+    newblock = (char *)malloc(realsize);  /* alloc a new block */
     if (newblock == NULL) return NULL;
     if (newblock == NULL) return NULL;
+    if (oldsize > size) oldsize = size;
     if (block) {
     if (block) {
-      size_t oldsize = *blocksize(block);
-      if (oldsize > size) oldsize = size;
       memcpy(newblock+HEADER, block, oldsize);
       memcpy(newblock+HEADER, block, oldsize);
       freeblock(block);  /* erase (and check) old copy */
       freeblock(block);  /* erase (and check) old copy */
     }
     }
+    /* initialize new part of the block with something `weird' */
+    memset(newblock+HEADER+oldsize, -MARK, size-oldsize);
     memdebug_total += size;
     memdebug_total += size;
-    if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total;
+    if (memdebug_total > memdebug_maxmem)
+      memdebug_maxmem = memdebug_total;
     memdebug_numblocks++;
     memdebug_numblocks++;
     *(size_t *)newblock = size;
     *(size_t *)newblock = size;
     for (i=0;i<MARKSIZE;i++)
     for (i=0;i<MARKSIZE;i++)
@@ -102,20 +105,26 @@ static void *debug_realloc (void *block, size_t size) {
 
 
 
 
 /* }====================================================================== */
 /* }====================================================================== */
-#endif
-
 
 
+#else
+/* no debug */
 
 
 /*
 /*
 ** Real ISO (ANSI) systems do not need these tests;
 ** Real ISO (ANSI) systems do not need these tests;
 ** but some systems (Sun OS) are not that ISO...
 ** but some systems (Sun OS) are not that ISO...
 */
 */
 #ifdef OLD_ANSI
 #ifdef OLD_ANSI
-#define realloc(b,s)	((b) == NULL ? malloc(s) : (realloc)(b, s))
-#define free(b)		if (b) (free)(b)
+#define basicrealloc(b,os,s)	((b) == NULL ? malloc(s) : realloc(b, s))
+#define basicfree(b,s)		if (b) free(b)
+#else
+#define basicrealloc(b,os,s)	realloc(b,s)
+#define basicfree(b,s)		free(b)
+
 #endif
 #endif
 
 
 
 
+#endif
+
 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
                     int limit, const char *errormsg) {
                     int limit, const char *errormsg) {
   void *newblock;
   void *newblock;
@@ -127,7 +136,8 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
       newsize = limit;  /* still have at least MINPOWER2 free places */
       newsize = limit;  /* still have at least MINPOWER2 free places */
     else lua_error(L, errormsg);
     else lua_error(L, errormsg);
   }
   }
-  newblock = luaM_realloc(L, block, (luint32)newsize*(luint32)size_elems);
+  newblock = luaM_realloc(L, block, (luint32)(*size)*(luint32)size_elems,
+                                    (luint32)newsize*(luint32)size_elems);
   *size = newsize;  /* update only when everything else is OK */
   *size = newsize;  /* update only when everything else is OK */
   return newblock;
   return newblock;
 }
 }
@@ -136,20 +146,25 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
 /*
 /*
 ** generic allocation routine.
 ** generic allocation routine.
 */
 */
-void *luaM_realloc (lua_State *L, void *block, luint32 size) {
+void *luaM_realloc (lua_State *L, void *block, luint32 oldsize, luint32 size) {
   if (size == 0) {
   if (size == 0) {
-    free(block);  /* block may be NULL; that is OK for free */
-    return NULL;
+    basicfree(block, oldsize);  /* block may be NULL; that is OK for free */
+    block = NULL;
   }
   }
   else if (size >= MAX_SIZET)
   else if (size >= MAX_SIZET)
     lua_error(L, "memory allocation error: block too big");
     lua_error(L, "memory allocation error: block too big");
-  block = realloc(block, size);
-  if (block == NULL) {
-    if (L)
-      luaD_breakrun(L, LUA_ERRMEM);  /* break run without error message */
-    else return NULL;  /* error before creating state! */
+  else {
+    block = basicrealloc(block, oldsize, size);
+    if (block == NULL) {
+      if (L)
+        luaD_breakrun(L, LUA_ERRMEM);  /* break run without error message */
+      else return NULL;  /* error before creating state! */
+    }
+  }
+  if (L) {
+    L->nblocks -= oldsize;
+    L->nblocks += size;
   }
   }
   return block;
   return block;
 }
 }
 
 
-

+ 15 - 7
lmem.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lmem.h,v 1.17 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lmem.h,v 1.18 2000/12/26 18:46:09 roberto Exp roberto $
 ** Interface to Memory Manager
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -13,21 +13,29 @@
 #include "llimits.h"
 #include "llimits.h"
 #include "lua.h"
 #include "lua.h"
 
 
-void *luaM_realloc (lua_State *L, void *oldblock, luint32 size);
+void *luaM_realloc (lua_State *L, void *oldblock, luint32 oldsize,
+                    luint32 size);
+
 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
 void *luaM_growaux (lua_State *L, void *block, int *size, int size_elem,
                     int limit, const char *errormsg);
                     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_free(L, b, s)	luaM_realloc(L, (b), (s), 0)
+#define luaM_freelem(L, b, t)	luaM_realloc(L, (b), sizeof(t), 0)
+#define luaM_freearray(L, b, n, t)	luaM_realloc(L, (b), \
+                                          ((luint32)(n)*(luint32)sizeof(t)), 0)
+
+#define luaM_malloc(L, t)	luaM_realloc(L, NULL, 0, (t))
 #define luaM_new(L, t)          ((t *)luaM_malloc(L, sizeof(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_newvector(L, n,t)  ((t *)luaM_malloc(L, \
+                                         (luint32)(n)*(luint32)sizeof(t)))
 
 
 #define luaM_growvector(L,v,nelems,size,t,limit,e) \
 #define luaM_growvector(L,v,nelems,size,t,limit,e) \
           if (((nelems)+1) > (size)) \
           if (((nelems)+1) > (size)) \
             ((v)=(t *)luaM_growaux(L,v,&(size),sizeof(t),limit,e))
             ((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)))
+#define luaM_reallocvector(L, v,oldn,n,t) \
+	((v)=(t *)luaM_realloc(L, v,(luint32)(oldn)*(luint32)sizeof(t), \
+                                    (luint32)(n)*(luint32)sizeof(t)))
 
 
 
 
 #ifdef LUA_DEBUG
 #ifdef LUA_DEBUG

+ 2 - 3
lobject.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lobject.c,v 1.56 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lobject.c,v 1.57 2000/12/04 18:33:40 roberto Exp roberto $
 ** Some generic functions over Lua objects
 ** Some generic functions over Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -57,8 +57,7 @@ int luaO_equalObj (const TObject *t1, const TObject *t2) {
 
 
 char *luaO_openspace (lua_State *L, size_t n) {
 char *luaO_openspace (lua_State *L, size_t n) {
   if (n > L->Mbuffsize) {
   if (n > L->Mbuffsize) {
-    luaM_reallocvector(L, L->Mbuffer, n, char);
-    L->nblocks += (n - L->Mbuffsize)*sizeof(char);
+    luaM_reallocvector(L, L->Mbuffer, L->Mbuffsize, n, char);
     L->Mbuffsize = n;
     L->Mbuffsize = n;
   }
   }
   return L->Mbuffer;
   return L->Mbuffer;

+ 7 - 7
lobject.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lobject.h,v 1.83 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lobject.h,v 1.84 2000/12/04 18:33:40 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -102,13 +102,13 @@ typedef struct TString {
 */
 */
 typedef struct Proto {
 typedef struct Proto {
   lua_Number *knum;  /* numbers used by the function */
   lua_Number *knum;  /* numbers used by the function */
-  int nknum;  /* size of `knum' */
+  int sizeknum;  /* size of `knum' */
   struct TString **kstr;  /* strings used by the function */
   struct TString **kstr;  /* strings used by the function */
-  int nkstr;  /* size of `kstr' */
+  int sizekstr;  /* size of `kstr' */
   struct Proto **kproto;  /* functions defined inside the function */
   struct Proto **kproto;  /* functions defined inside the function */
-  int nkproto;  /* size of `kproto' */
+  int sizekproto;  /* size of `kproto' */
   Instruction *code;
   Instruction *code;
-  int ncode;  /* size of `code'; when 0 means an incomplete `Proto' */
+  int sizecode;
   short numparams;
   short numparams;
   short is_vararg;
   short is_vararg;
   short maxstacksize;
   short maxstacksize;
@@ -116,9 +116,9 @@ typedef struct Proto {
   struct Proto *next;
   struct Proto *next;
   /* debug information */
   /* debug information */
   int *lineinfo;  /* map from opcodes to source lines */
   int *lineinfo;  /* map from opcodes to source lines */
-  int nlineinfo;  /* size of `lineinfo' */
-  int nlocvars;
+  int sizelineinfo;  /* size of `lineinfo' */
   struct LocVar *locvars;  /* information about local variables */
   struct LocVar *locvars;  /* information about local variables */
+  int sizelocvars;
   int lineDefined;
   int lineDefined;
   TString  *source;
   TString  *source;
 } Proto;
 } Proto;

+ 30 - 25
lparser.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lparser.c,v 1.119 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: lparser.c,v 1.120 2000/12/26 18:46:09 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -120,10 +120,10 @@ static void check_match (LexState *ls, int what, int who, int where) {
 static int string_constant (FuncState *fs, TString *s) {
 static int string_constant (FuncState *fs, TString *s) {
   Proto *f = fs->f;
   Proto *f = fs->f;
   int c = s->u.s.constindex;
   int c = s->u.s.constindex;
-  if (c >= f->nkstr || f->kstr[c] != s) {
-    luaM_growvector(fs->L, f->kstr, f->nkstr, fs->sizekstr, TString *,
+  if (c >= fs->nkstr || f->kstr[c] != s) {
+    luaM_growvector(fs->L, f->kstr, fs->nkstr, f->sizekstr, TString *,
                     MAXARG_U, "constant table overflow");
                     MAXARG_U, "constant table overflow");
-    c = f->nkstr++;
+    c = fs->nkstr++;
     f->kstr[c] = s;
     f->kstr[c] = s;
     s->u.s.constindex = c;  /* hint for next time */
     s->u.s.constindex = c;  /* hint for next time */
   }
   }
@@ -151,11 +151,12 @@ static int checkname (LexState *ls) {
 
 
 
 
 static int luaI_registerlocalvar (LexState *ls, TString *varname) {
 static int luaI_registerlocalvar (LexState *ls, TString *varname) {
-  Proto *f = ls->fs->f;
-  luaM_growvector(ls->L, f->locvars, f->nlocvars, ls->fs->sizelocvars,
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;
+  luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
                   LocVar, MAX_INT, "");
                   LocVar, MAX_INT, "");
-  f->locvars[f->nlocvars].varname = varname;
-  return f->nlocvars++;
+  f->locvars[fs->nlocvars].varname = varname;
+  return fs->nlocvars++;
 }
 }
 
 
 
 
@@ -295,10 +296,10 @@ static void pushclosure (LexState *ls, FuncState *func) {
   int i;
   int i;
   for (i=0; i<func->nupvalues; i++)
   for (i=0; i<func->nupvalues; i++)
     luaK_tostack(ls, &func->upvalues[i], 1);
     luaK_tostack(ls, &func->upvalues[i], 1);
-  luaM_growvector(ls->L, f->kproto, f->nkproto, fs->sizekproto, Proto *,
+  luaM_growvector(ls->L, f->kproto, fs->nkproto, f->sizekproto, Proto *,
                   MAXARG_A, "constant table overflow");
                   MAXARG_A, "constant table overflow");
-  f->kproto[f->nkproto++] = func->f;
-  luaK_code2(fs, OP_CLOSURE, f->nkproto-1, func->nupvalues);
+  f->kproto[fs->nkproto++] = func->f;
+  luaK_code2(fs, OP_CLOSURE, fs->nkproto-1, func->nupvalues);
 }
 }
 
 
 
 
@@ -313,12 +314,11 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->lasttarget = 0;
   fs->lasttarget = 0;
   fs->jlt = NO_JUMP;
   fs->jlt = NO_JUMP;
   fs->stacklevel = 0;
   fs->stacklevel = 0;
-  fs->sizekstr = 0;
-  fs->sizekproto = 0;
-  fs->sizeknum = 0;
-  fs->sizelineinfo = 0;
-  fs->sizecode = 0;
-  fs->sizelocvars = 0;
+  fs->nkstr = 0;
+  fs->nkproto = 0;
+  fs->nknum = 0;
+  fs->nlineinfo = 0;
+  fs->nlocvars = 0;
   fs->nactloc = 0;
   fs->nactloc = 0;
   fs->nupvalues = 0;
   fs->nupvalues = 0;
   fs->lastline = 0;
   fs->lastline = 0;
@@ -337,15 +337,20 @@ static void close_func (LexState *ls) {
   Proto *f = fs->f;
   Proto *f = fs->f;
   luaK_code0(fs, OP_END);
   luaK_code0(fs, OP_END);
   luaK_getlabel(fs);  /* close eventual list of pending jumps */
   luaK_getlabel(fs);  /* close eventual list of pending jumps */
-  luaM_reallocvector(L, f->code, fs->pc, Instruction);
-  luaM_reallocvector(L, f->kstr, f->nkstr, TString *);
-  luaM_reallocvector(L, f->knum, f->nknum, lua_Number);
-  luaM_reallocvector(L, f->kproto, f->nkproto, Proto *);
   removelocalvars(ls, fs->nactloc);
   removelocalvars(ls, fs->nactloc);
-  luaM_reallocvector(L, f->locvars, f->nlocvars, LocVar);
-  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 */
+  luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
+  f->sizecode = fs->pc;
+  luaM_reallocvector(L, f->kstr, f->sizekstr, fs->nkstr, TString *);
+  f->sizekstr = fs->nkstr;
+  luaM_reallocvector(L, f->knum, f->sizeknum, fs->nknum, lua_Number);
+  f->sizeknum = fs->nknum;
+  luaM_reallocvector(L, f->kproto, f->sizekproto, fs->nkproto, Proto *);
+  f->sizekproto = fs->nkproto;
+  luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
+  f->sizelocvars = fs->nlocvars;
+  luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int);
+  f->lineinfo[fs->nlineinfo++] = MAX_INT;  /* end flag */
+  f->sizelineinfo = fs->nlineinfo;
   ls->fs = fs->prev;
   ls->fs = fs->prev;
   LUA_ASSERT(fs->bl == NULL, "wrong list end");
   LUA_ASSERT(fs->bl == NULL, "wrong list end");
 }
 }

+ 7 - 8
lparser.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lparser.h,v 1.27 2000/11/30 18:50:47 roberto Exp roberto $
+** $Id: lparser.h,v 1.28 2000/12/26 18:46:09 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -41,16 +41,15 @@ typedef struct FuncState {
   struct FuncState *prev;  /* enclosing function */
   struct FuncState *prev;  /* enclosing function */
   struct LexState *ls;  /* lexical state */
   struct LexState *ls;  /* lexical state */
   struct lua_State *L;  /* copy of the Lua state */
   struct lua_State *L;  /* copy of the Lua state */
-  int pc;  /* next position to code */
+  int pc;  /* next position to code (equivalent to `ncode') */
   int lasttarget;   /* `pc' of last `jump target' */
   int lasttarget;   /* `pc' of last `jump target' */
   int jlt;  /* list of jumps to `lasttarget' */
   int jlt;  /* list of jumps to `lasttarget' */
   int stacklevel;  /* number of values on activation register */
   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 nkstr;  /* number of elements in `kstr' */
+  int nkproto;  /* number of elements in `kproto' */
+  int nknum;  /* number of elements in `knum' */
+  int nlineinfo;  /* number of elements in `lineinfo' */
+  int nlocvars;  /* number of elements in `locvars' */
   int nactloc;  /* number of active local variables */
   int nactloc;  /* number of active local variables */
   int nupvalues;  /* number of upvalues */
   int nupvalues;  /* number of upvalues */
   int lastline;  /* line where last `lineinfo' was generated */
   int lastline;  /* line where last `lineinfo' was generated */

+ 9 - 14
lstate.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstate.c,v 1.48 2000/10/30 16:29:59 roberto Exp roberto $
+** $Id: lstate.c,v 1.49 2000/12/26 18:46:09 roberto Exp roberto $
 ** Global State
 ** Global State
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -58,8 +58,8 @@ static void f_luaopen (lua_State *L, void *ud) {
 #ifdef LUA_DEBUG
 #ifdef LUA_DEBUG
   luaB_opentests(L);
   luaB_opentests(L);
   if (lua_state == NULL) lua_state = L;  /* keep first state to be opened */
   if (lua_state == NULL) lua_state = L;  /* keep first state to be opened */
-#endif
   LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
   LUA_ASSERT(lua_gettop(L) == 0, "wrong API stack");
+#endif
 }
 }
 
 
 
 
@@ -67,10 +67,10 @@ LUA_API lua_State *lua_open (int stacksize) {
   lua_State *L = luaM_new(NULL, lua_State);
   lua_State *L = luaM_new(NULL, lua_State);
   if (L == NULL) return NULL;  /* memory allocation error */
   if (L == NULL) return NULL;  /* memory allocation error */
   L->stack = NULL;
   L->stack = NULL;
+  L->stacksize = 0;
   L->strt.size = L->udt.size = 0;
   L->strt.size = L->udt.size = 0;
   L->strt.nuse = L->udt.nuse = 0;
   L->strt.nuse = L->udt.nuse = 0;
-  L->strt.hash = NULL;
-  L->udt.hash = NULL;
+  L->strt.hash = L->udt.hash = NULL;
   L->Mbuffer = NULL;
   L->Mbuffer = NULL;
   L->Mbuffsize = 0;
   L->Mbuffsize = 0;
   L->rootproto = NULL;
   L->rootproto = NULL;
@@ -106,17 +106,12 @@ LUA_API void lua_close (lua_State *L) {
   LUA_ASSERT(L->rootcl == NULL, "list should be empty");
   LUA_ASSERT(L->rootcl == NULL, "list should be empty");
   LUA_ASSERT(L->roottable == NULL, "list should be empty");
   LUA_ASSERT(L->roottable == NULL, "list should be empty");
   luaS_freeall(L);
   luaS_freeall(L);
-  if (L->stack)
-    L->nblocks -= (L->stack_last - L->stack + 1)*sizeof(TObject);
-  luaM_free(L, L->stack);
-  L->nblocks -= L->ntag*sizeof(struct TM);
-  luaM_free(L, L->TMtable);
-  L->nblocks -= (L->nref)*sizeof(struct Ref);
-  luaM_free(L, L->refArray);
-  L->nblocks -= (L->Mbuffsize)*sizeof(char);
-  luaM_free(L, L->Mbuffer);
+  luaM_freearray(L, L->stack, L->stacksize, TObject);
+  luaM_freearray(L, L->TMtable, L->sizeTM, struct TM);
+  luaM_freearray(L, L->refArray, L->sizeref, struct Ref);
+  luaM_freearray(L, L->Mbuffer, L->Mbuffsize, char);
   LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
   LUA_ASSERT(L->nblocks == sizeof(lua_State), "wrong count for nblocks");
-  luaM_free(L, L);
+  luaM_freelem(L, L, lua_State);
   LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
   LUA_ASSERT(L != lua_state || memdebug_numblocks == 0, "memory leak!");
   LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
   LUA_ASSERT(L != lua_state || memdebug_total == 0,"memory leak!");
 }
 }

+ 8 - 27
lstring.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.c,v 1.46 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lstring.c,v 1.47 2000/12/22 16:57:46 roberto Exp roberto $
 ** String table (keeps all strings handled by Lua)
 ** String table (keeps all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -15,32 +15,18 @@
 #include "lstring.h"
 #include "lstring.h"
 
 
 
 
-/*
-** type equivalent to TString, but with maximum alignment requirements
-*/
-union L_UTString {
-  TString ts;
-  union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
-};
-
-
 
 
 void luaS_init (lua_State *L) {
 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;
+  luaS_resize(L, &L->strt, MINPOWER2);
+  luaS_resize(L, &L->udt, MINPOWER2);
 }
 }
 
 
 
 
 void luaS_freeall (lua_State *L) {
 void luaS_freeall (lua_State *L) {
   LUA_ASSERT(L->strt.nuse==0, "non-empty string table");
   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);
+  luaM_freearray(L, L->strt.hash, L->strt.size, TString *);
   LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
   LUA_ASSERT(L->udt.nuse==0, "non-empty udata table");
-  luaM_free(L, L->udt.hash);
+  luaM_freearray(L, L->udt.hash, L->udt.size, TString *);
 }
 }
 
 
 
 
@@ -71,9 +57,7 @@ void luaS_resize (lua_State *L, stringtable *tb, int newsize) {
       p = next;
       p = next;
     }
     }
   }
   }
-  luaM_free(L, tb->hash);
-  L->nblocks -= tb->size*sizeof(TString *);
-  L->nblocks += newsize*sizeof(TString *);
+  luaM_freearray(L, tb->hash, tb->size, TString *);
   tb->size = newsize;
   tb->size = newsize;
   tb->hash = newhash;
   tb->hash = newhash;
 }
 }
@@ -106,23 +90,20 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
   ts->u.s.constindex = 0;
   ts->u.s.constindex = 0;
   memcpy(ts->str, str, l);
   memcpy(ts->str, str, l);
   ts->str[l] = 0;  /* ending 0 */
   ts->str[l] = 0;  /* ending 0 */
-  L->nblocks += sizestring(l);
   newentry(L, &L->strt, ts, h1);  /* insert it on table */
   newentry(L, &L->strt, ts, h1);  /* insert it on table */
   return ts;
   return ts;
 }
 }
 
 
 
 
 TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
 TString *luaS_newudata (lua_State *L, size_t s, void *udata) {
-  union L_UTString *uts = (union L_UTString *)luaM_malloc(L,
-                                (luint32)sizeof(union L_UTString)+s);
+  union L_UTString *uts = (union L_UTString *)luaM_malloc(L, sizeudata(s));
   TString *ts = &uts->ts;
   TString *ts = &uts->ts;
   ts->marked = 0;
   ts->marked = 0;
   ts->nexthash = NULL;
   ts->nexthash = NULL;
   ts->len = s;
   ts->len = s;
   ts->u.d.tag = 0;
   ts->u.d.tag = 0;
   ts->u.d.value = (udata == NULL) ? uts+1 : udata;
   ts->u.d.value = (udata == NULL) ? uts+1 : udata;
-  L->nblocks += sizestring(s);
- /* insert it on table */
+  /* insert it on table */
   newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
   newentry(L, &L->udt, ts, IntPoint(ts->u.d.value) & (L->udt.size-1));
   return ts;
   return ts;
 }
 }

+ 14 - 1
lstring.h

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lstring.h,v 1.24 2000/10/30 17:49:19 roberto Exp roberto $
+** $Id: lstring.h,v 1.25 2000/11/24 17:39:56 roberto Exp roberto $
 ** String table (keep all strings handled by Lua)
 ** String table (keep all strings handled by Lua)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -12,6 +12,17 @@
 #include "lstate.h"
 #include "lstate.h"
 
 
 
 
+
+/*
+** type equivalent to TString, but with maximum alignment requirements
+*/
+union L_UTString {
+  TString ts;
+  union L_Umaxalign dummy;  /* ensures maximum alignment for `local' udata */
+};
+
+
+
 /*
 /*
 ** any TString with mark>=FIXMARK is never collected.
 ** any TString with mark>=FIXMARK is never collected.
 ** Marks>=RESERVEDMARK are used to identify reserved words.
 ** Marks>=RESERVEDMARK are used to identify reserved words.
@@ -23,6 +34,8 @@
 #define sizestring(l)	((lint32)sizeof(TString) + \
 #define sizestring(l)	((lint32)sizeof(TString) + \
                          ((lint32)(l+1)-TSPACK)*(lint32)sizeof(char))
                          ((lint32)(l+1)-TSPACK)*(lint32)sizeof(char))
 
 
+#define sizeudata(l)	((luint32)sizeof(union L_UTString)+(l))
+
 
 
 void luaS_init (lua_State *L);
 void luaS_init (lua_State *L);
 void luaS_resize (lua_State *L, stringtable *tb, int newsize);
 void luaS_resize (lua_State *L, stringtable *tb, int newsize);

+ 4 - 11
ltable.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltable.c,v 1.60 2000/12/04 18:33:40 roberto Exp roberto $
+** $Id: ltable.c,v 1.61 2000/12/22 16:57:46 roberto Exp roberto $
 ** Lua tables (hash)
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -27,9 +27,6 @@
 #include "ltable.h"
 #include "ltable.h"
 
 
 
 
-#define gcsize(L, n)	(sizeof(Hash)+(n)*sizeof(Node))
-
-
 
 
 #define TagDefault LUA_TTABLE
 #define TagDefault LUA_TTABLE
 
 
@@ -167,8 +164,6 @@ static void setnodevector (lua_State *L, Hash *t, luint32 size) {
     ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
     ttype(&t->node[i].key) = ttype(&t->node[i].val) = LUA_TNIL;
     t->node[i].next = NULL;
     t->node[i].next = NULL;
   }
   }
-  L->nblocks -= gcsize(L, t->size);  /* old size */
-  L->nblocks += gcsize(L, size);  /* new size */
   t->size = size;
   t->size = size;
   t->firstfree = &t->node[size-1];  /* first free position to be used */
   t->firstfree = &t->node[size-1];  /* first free position to be used */
 }
 }
@@ -181,7 +176,6 @@ Hash *luaH_new (lua_State *L, int size) {
   L->roottable = t;
   L->roottable = t;
   t->mark = t;
   t->mark = t;
   t->size = 0;
   t->size = 0;
-  L->nblocks += gcsize(L, 0);
   t->node = NULL;
   t->node = NULL;
   setnodevector(L, t, luaO_power2(size));
   setnodevector(L, t, luaO_power2(size));
   return t;
   return t;
@@ -189,9 +183,8 @@ Hash *luaH_new (lua_State *L, int size) {
 
 
 
 
 void luaH_free (lua_State *L, Hash *t) {
 void luaH_free (lua_State *L, Hash *t) {
-  L->nblocks -= gcsize(L, t->size);
-  luaM_free(L, t->node);
-  luaM_free(L, t);
+  luaM_freearray(L, t->node, t->size, Node);
+  luaM_freelem(L, t, Hash);
 }
 }
 
 
 
 
@@ -226,7 +219,7 @@ static void rehash (lua_State *L, Hash *t) {
     if (ttype(&old->val) != LUA_TNIL)
     if (ttype(&old->val) != LUA_TNIL)
       *luaH_set(L, t, &old->key) = old->val;
       *luaH_set(L, t, &old->key) = old->val;
   }
   }
-  luaM_free(L, nold);  /* free old array */
+  luaM_freearray(L, nold, oldsize, Node);  /* free old array */
 }
 }
 
 
 
 

+ 2 - 2
ltests.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltests.c,v 1.53 2000/10/30 16:29:59 roberto Exp roberto $
+** $Id: ltests.c,v 1.54 2000/10/31 13:10:24 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -116,7 +116,7 @@ static int liststrings (lua_State *L) {
                  1, "Lua function expected");
                  1, "Lua function expected");
   p = clvalue(luaA_index(L, 1))->f.l;
   p = clvalue(luaA_index(L, 1))->f.l;
   lua_newtable(L);
   lua_newtable(L);
-  for (i=0; i<p->nkstr; i++) {
+  for (i=0; i<p->sizekstr; i++) {
     lua_pushnumber(L, i+1);
     lua_pushnumber(L, i+1);
     lua_pushstring(L, p->kstr[i]->str);
     lua_pushstring(L, p->kstr[i]->str);
     lua_settable(L, -3);
     lua_settable(L, -3);

+ 2 - 4
ltm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: ltm.c,v 1.57 2000/11/30 18:50:47 roberto Exp roberto $
+** $Id: ltm.c,v 1.58 2000/12/26 18:46:09 roberto Exp roberto $
 ** Tag methods
 ** Tag methods
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -75,9 +75,8 @@ static void init_entry (lua_State *L, int tag) {
 
 
 void luaT_init (lua_State *L) {
 void luaT_init (lua_State *L) {
   int t;
   int t;
+  L->TMtable = luaM_newvector(L, NUM_TAGS+2, struct TM);
   L->sizeTM = NUM_TAGS+2;
   L->sizeTM = NUM_TAGS+2;
-  L->TMtable = luaM_newvector(L, L->sizeTM, struct TM);
-  L->nblocks += NUM_TAGS*sizeof(struct TM);
   L->ntag = NUM_TAGS;
   L->ntag = NUM_TAGS;
   for (t=0; t<L->ntag; t++)
   for (t=0; t<L->ntag; t++)
     init_entry(L, t);
     init_entry(L, t);
@@ -87,7 +86,6 @@ void luaT_init (lua_State *L) {
 LUA_API int lua_newtag (lua_State *L) {
 LUA_API int lua_newtag (lua_State *L) {
   luaM_growvector(L, L->TMtable, L->ntag, L->sizeTM, struct TM,
   luaM_growvector(L, L->TMtable, L->ntag, L->sizeTM, struct TM,
                   MAX_INT, "tag table overflow");
                   MAX_INT, "tag table overflow");
-  L->nblocks += sizeof(struct TM);
   init_entry(L, L->ntag);
   init_entry(L, L->ntag);
   return L->ntag++;
   return L->ntag++;
 }
 }

+ 8 - 8
lundump.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lundump.c,v 1.34 2000/11/07 12:44:44 roberto Exp roberto $
+** $Id: lundump.c,v 1.35 2000/12/04 18:33:40 roberto Exp roberto $
 ** load bytecodes from files
 ** load bytecodes from files
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -104,17 +104,17 @@ static TString* LoadString (lua_State* L, ZIO* Z, int swap)
 
 
 static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
 static void LoadCode (lua_State* L, Proto* tf, ZIO* Z, int swap)
 {
 {
- int size=LoadInt(L,Z,swap);
+ int size;
+ tf->sizecode=size=LoadInt(L,Z,swap);
  tf->code=luaM_newvector(L,size,Instruction);
  tf->code=luaM_newvector(L,size,Instruction);
  LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
  LoadVector(L,tf->code,size,sizeof(*tf->code),Z,swap);
  if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
  if (tf->code[size-1]!=OP_END) luaO_verror(L,"bad code in `%.99s'",ZNAME(Z));
- luaF_protook(L,tf,size);
 }
 }
 
 
 static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
 static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
 {
 {
  int i,n;
  int i,n;
- tf->nlocvars=n=LoadInt(L,Z,swap);
+ tf->sizelocvars=n=LoadInt(L,Z,swap);
  tf->locvars=luaM_newvector(L,n,LocVar);
  tf->locvars=luaM_newvector(L,n,LocVar);
  for (i=0; i<n; i++)
  for (i=0; i<n; i++)
  {
  {
@@ -127,7 +127,7 @@ static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z, int swap)
 static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
 static void LoadLines (lua_State* L, Proto* tf, ZIO* Z, int swap)
 {
 {
  int n;
  int n;
- tf->nlineinfo=n=LoadInt(L,Z,swap);
+ tf->sizelineinfo=n=LoadInt(L,Z,swap);
  tf->lineinfo=luaM_newvector(L,n,int);
  tf->lineinfo=luaM_newvector(L,n,int);
  LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
  LoadVector(L,tf->lineinfo,n,sizeof(*tf->lineinfo),Z,swap);
 }
 }
@@ -137,14 +137,14 @@ static Proto* LoadFunction (lua_State* L, ZIO* Z, int swap);
 static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
 static void LoadConstants (lua_State* L, Proto* tf, ZIO* Z, int swap)
 {
 {
  int i,n;
  int i,n;
- tf->nkstr=n=LoadInt(L,Z,swap);
+ tf->sizekstr=n=LoadInt(L,Z,swap);
  tf->kstr=luaM_newvector(L,n,TString*);
  tf->kstr=luaM_newvector(L,n,TString*);
  for (i=0; i<n; i++)
  for (i=0; i<n; i++)
   tf->kstr[i]=LoadString(L,Z,swap);
   tf->kstr[i]=LoadString(L,Z,swap);
- tf->nknum=n=LoadInt(L,Z,swap);
+ tf->sizeknum=n=LoadInt(L,Z,swap);
  tf->knum=luaM_newvector(L,n,lua_Number);
  tf->knum=luaM_newvector(L,n,lua_Number);
  LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
  LoadVector(L,tf->knum,n,sizeof(*tf->knum),Z,swap);
- tf->nkproto=n=LoadInt(L,Z,swap);
+ tf->sizekproto=n=LoadInt(L,Z,swap);
  tf->kproto=luaM_newvector(L,n,Proto*);
  tf->kproto=luaM_newvector(L,n,Proto*);
  for (i=0; i<n; i++)
  for (i=0; i<n; i++)
   tf->kproto[i]=LoadFunction(L,Z,swap);
   tf->kproto[i]=LoadFunction(L,Z,swap);

+ 3 - 3
lvm.c

@@ -1,5 +1,5 @@
 /*
 /*
-** $Id: lvm.c,v 1.147 2000/11/24 17:39:56 roberto Exp roberto $
+** $Id: lvm.c,v 1.148 2000/12/04 18:33:40 roberto Exp roberto $
 ** Lua virtual machine
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 ** See Copyright Notice in lua.h
 */
 */
@@ -35,7 +35,7 @@
 ** Extra stack size to run a function:
 ** Extra stack size to run a function:
 ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
 ** TAG_LINE(1), NAME(1), TM calls(3) (plus some extra...)
 */
 */
-#define	EXTRA_STACK	8
+#define	EXTRA_FSTACK	8
 
 
 
 
 
 
@@ -355,7 +355,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) {
   TString **const kstr = tf->kstr;
   TString **const kstr = tf->kstr;
   const lua_Hook linehook = L->linehook;
   const lua_Hook linehook = L->linehook;
   infovalue(base-1)->pc = &pc;
   infovalue(base-1)->pc = &pc;
-  luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
+  luaD_checkstack(L, tf->maxstacksize+EXTRA_FSTACK);
   if (tf->is_vararg)  /* varargs? */
   if (tf->is_vararg)  /* varargs? */
     adjust_varargs(L, base, tf->numparams);
     adjust_varargs(L, base, tf->numparams);
   else
   else