浏览代码

Lua kernel does not use malloc/free functions.

Roberto Ierusalimschy 22 年之前
父节点
当前提交
b97fb932ec
共有 8 个文件被更改,包括 116 次插入105 次删除
  1. 18 1
      lauxlib.c
  2. 3 1
      lauxlib.h
  3. 27 38
      lmem.c
  4. 22 29
      lstate.c
  5. 3 1
      lstate.h
  6. 22 25
      ltests.c
  7. 12 8
      ltests.h
  8. 9 2
      lua.h

+ 18 - 1
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.102 2003/05/16 18:59:08 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.103 2003/10/01 16:50:53 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -9,6 +9,7 @@
 #include <errno.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 
@@ -558,6 +559,22 @@ LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
 /* }====================================================== */
 
 
+static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
+  (void)ud;
+  if (nsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+  else 
+    return realloc(ptr, nsize);
+}
+
+
+LUALIB_API lua_State *luaL_newstate (void) {
+  return lua_newstate(l_alloc, NULL);
+}
+
+
 /*
 ** {======================================================
 ** compatibility code

+ 3 - 1
lauxlib.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.h,v 1.59 2003/03/18 12:25:32 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.60 2003/04/03 13:35:34 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -62,6 +62,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename);
 LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t sz,
                                 const char *name);
 
+LUALIB_API lua_State *(luaL_newstate) (void);
+
 
 
 /*

+ 27 - 38
lmem.c

@@ -1,11 +1,11 @@
 /*
-** $Id: lmem.c,v 1.60 2002/11/21 14:14:42 roberto Exp roberto $
+** $Id: lmem.c,v 1.61 2002/12/04 17:38:31 roberto Exp roberto $
 ** Interface to Memory Manager
 ** See Copyright Notice in lua.h
 */
 
 
-#include <stdlib.h>
+#include <stddef.h>
 
 #define lmem_c
 
@@ -20,21 +20,23 @@
 
 
 /*
-** definition for realloc function. It must assure that l_realloc(NULL,
-** 0, x) allocates a new block (ANSI C assures that). (`os' is the old
-** block size; some allocators may use that.)
+** About the realloc function:
+** void * realloc (void *ud, void *ptr, size_t osize, size_t nsize);
+** (`osize' is the old size, `nsize' is the new size)
+**
+** Lua ensures that (ptr == NULL) iff (osize == 0).
+**
+** * realloc(ud, NULL, 0, x) creates a new block of size `x'
+**
+** * realloc(ud, p, x, 0) frees the block `p'
+** (in this specific case, realloc must return NULL).
+** particularly, realloc(ud, NULL, 0, 0) does nothing
+** (which is equivalent to free(NULL) in ANSI C)
+**
+** realloc returns NULL if it cannot create or reallocate the area
+** (any reallocation to an equal or smaller size cannot fail!)
 */
-#ifndef l_realloc
-#define l_realloc(b,os,s)	realloc(b,s)
-#endif
 
-/*
-** definition for free function. (`os' is the old block size; some
-** allocators may use that.)
-*/
-#ifndef l_free
-#define l_free(b,os)	free(b)
-#endif
 
 
 #define MINSIZEARRAY	4
@@ -62,30 +64,17 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
 /*
 ** generic allocation routine.
 */
-void *luaM_realloc (lua_State *L, void *block, lu_mem oldsize, lu_mem size) {
-  lua_assert((oldsize == 0) == (block == NULL));
-  if (size == 0) {
-    if (block != NULL) {
-      l_free(block, oldsize);
-      block = NULL;
-    }
-    else return NULL;  /* avoid `nblocks' computations when oldsize==size==0 */
-  }
-  else if (size >= MAX_SIZET)
+void *luaM_realloc (lua_State *L, void *block, lu_mem osize, lu_mem nsize) {
+  global_State *g = G(L);
+  lua_assert((osize == 0) == (block == NULL));
+  if (nsize >= MAX_SIZET)
     luaG_runerror(L, "memory allocation error: block too big");
-  else {
-    block = l_realloc(block, oldsize, size);
-    if (block == NULL) {
-      if (L)
-        luaD_throw(L, LUA_ERRMEM);
-      else return NULL;  /* error before creating state! */
-    }
-  }
-  if (L) {
-    lua_assert(G(L) != NULL && G(L)->nblocks > 0);
-    G(L)->nblocks -= oldsize;
-    G(L)->nblocks += size;
-  }
+  block = (*g->realloc)(g->ud, block, osize, nsize);
+  if (block == NULL && nsize > 0)
+    luaD_throw(L, LUA_ERRMEM);
+  lua_assert((nsize == 0) == (block == NULL));
+  g->nblocks -= osize;
+  g->nblocks += nsize;
   return block;
 }
 

+ 22 - 29
lstate.c

@@ -1,11 +1,11 @@
 /*
-** $Id: lstate.c,v 1.125 2003/07/16 20:51:47 roberto Exp roberto $
+** $Id: lstate.c,v 1.126 2003/09/04 20:19:07 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
 
 
-#include <stdlib.h>
+#include <stddef.h>
 
 #define lstate_c
 
@@ -34,6 +34,11 @@ union UEXTRASPACE {L_Umaxalign a; LUA_USERSTATE b;};
 #endif
 
 
+#define state_size(x)	(sizeof(x) + EXTRASPACE)
+#define tostate(l)	(cast(lua_State *, cast(lu_byte *, l) + EXTRASPACE))
+#define fromstate(l)	(cast(lu_byte *, (l)) - EXTRASPACE)
+
+
 /*
 ** Main thread combines a thread state and the global state
 */
@@ -44,23 +49,6 @@ typedef struct LG {
   
 
 
-
-static lua_State *mallocstate (lua_State *L, size_t size) {
-  lu_byte *block = (lu_byte *)luaM_malloc(L, size + EXTRASPACE);
-  if (block == NULL) return NULL;
-  else {
-    block += EXTRASPACE;
-    return cast(lua_State *, block);
-  }
-}
-
-
-static void freestate (lua_State *L, lua_State *L1, size_t size) {
-  luaM_free(L, cast(lu_byte *, L1) - EXTRASPACE,
-               size + EXTRASPACE);
-}
-
-
 static void stack_init (lua_State *L1, lua_State *L) {
   L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TObject);
   L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
@@ -122,20 +110,21 @@ static void preinit_state (lua_State *L) {
 
 
 static void close_state (lua_State *L) {
+  global_State *g = G(L);
   luaF_close(L, L->stack);  /* close all upvalues for this thread */
   luaC_sweep(L, 1);  /* collect all elements */
-  lua_assert(G(L)->rootgc == NULL);
-  lua_assert(G(L)->rootudata == NULL);
+  lua_assert(g->rootgc == NULL);
+  lua_assert(g->rootudata == NULL);
   luaS_freeall(L);
-  luaZ_freebuffer(L, &G(L)->buff);
+  luaZ_freebuffer(L, &g->buff);
   freestack(L, L);
-  lua_assert(G(L)->nblocks == sizeof(LG));
-  freestate(NULL, L, sizeof(LG));
+  lua_assert(g->nblocks == sizeof(LG));
+  (*g->realloc)(g->ud, fromstate(L), state_size(LG), 0);
 }
 
 
 lua_State *luaE_newthread (lua_State *L) {
-  lua_State *L1 = mallocstate(L, sizeof(lua_State));
+  lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
   luaC_link(L, valtogco(L1), LUA_TTHREAD);
   preinit_state(L1);
   L1->l_G = L->l_G;
@@ -149,20 +138,24 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
   luaF_close(L1, L1->stack);  /* close all upvalues for this thread */
   lua_assert(L1->openupval == NULL);
   freestack(L, L1);
-  freestate(L, L1, sizeof(lua_State));
+  luaM_free(L, fromstate(L1), state_size(lua_State));
 }
 
 
-LUA_API lua_State *lua_open (void) {
-  lua_State *L = mallocstate(NULL, sizeof(LG));
+LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
+  lua_State *L;
   global_State *g;
-  if (L == NULL) return NULL;
+  void *l = (*f)(ud, NULL, 0, state_size(LG));
+  if (l == NULL) return NULL;
+  L = tostate(l);
   g = &((LG *)L)->g;
   L->tt = LUA_TTHREAD;
   L->marked = 0;
   L->next = L->gclist = NULL;
   preinit_state(L);
   L->l_G = g;
+  g->realloc = f;
+  g->ud = ud;
   g->mainthread = L;
   g->GCthreshold = 0;  /* mark it as unfinished state */
   g->strt.size = 0;

+ 3 - 1
lstate.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lstate.h,v 1.110 2003/04/28 19:26:16 roberto Exp roberto $
+** $Id: lstate.h,v 1.111 2003/07/16 20:49:02 roberto Exp roberto $
 ** Global State
 ** See Copyright Notice in lua.h
 */
@@ -101,6 +101,8 @@ typedef struct global_State {
   GCObject *rootgc;  /* list of (almost) all collectable objects */
   GCObject *rootudata;   /* (separated) list of all userdata */
   GCObject *tmudata;  /* list of userdata to be GC */
+  lua_Alloc realloc;  /* function to reallocate memory */
+  void *ud;         /* auxiliary data to `realloc' */
   Mbuffer buff;  /* temporary buffer for string concatentation */
   lu_mem GCthreshold;
   lu_mem nblocks;  /* number of `bytes' currently allocated */

+ 22 - 25
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 1.162 2003/07/09 12:08:43 roberto Exp roberto $
+** $Id: ltests.c,v 1.163 2003/07/29 19:26:34 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -80,10 +80,8 @@ static void setnameval (lua_State *L, const char *name, int val) {
 #define fillmem(mem,size)	/* empty */
 #endif
 
-unsigned long memdebug_numblocks = 0;
-unsigned long memdebug_total = 0;
-unsigned long memdebug_maxmem = 0;
-unsigned long memdebug_memlimit = ULONG_MAX;
+
+Memcontrol memcontrol = {0L, 0L, 0L, ULONG_MAX};
 
 
 static void *checkblock (void *block, size_t size) {
@@ -95,27 +93,26 @@ static void *checkblock (void *block, size_t size) {
 }
 
 
-static void freeblock (void *block, size_t size) {
+static void freeblock (Memcontrol *mc, void *block, size_t size) {
   if (block) {
     lua_assert(checkblocksize(block, size));
     block = checkblock(block, size);
     fillmem(block, size+HEADER+MARKSIZE);  /* erase block */
     free(block);  /* free original block */
-    memdebug_numblocks--;
-    memdebug_total -= size;
+    mc->numblocks--;
+    mc->total -= size;
   }
 }
 
 
-void *debug_realloc (void *block, size_t oldsize, size_t size) {
+void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) {
+  Memcontrol *mc = cast(Memcontrol *, ud);
   lua_assert(oldsize == 0 || checkblocksize(block, oldsize));
-  /* ISO does not specify what realloc(NULL, 0) does */
-  lua_assert(block != NULL || size > 0);
   if (size == 0) {
-    freeblock(block, oldsize);
+    freeblock(mc, block, oldsize);
     return NULL;
   }
-  else if (size > oldsize && memdebug_total+size-oldsize > memdebug_memlimit)
+  else if (size > oldsize && mc->total+size-oldsize > mc->memlimit)
     return NULL;  /* to test memory allocation errors */
   else {
     void *newblock;
@@ -127,14 +124,14 @@ void *debug_realloc (void *block, size_t oldsize, size_t size) {
     if (newblock == NULL) return NULL;
     if (block) {
       memcpy(cast(char *, newblock)+HEADER, block, commonsize);
-      freeblock(block, oldsize);  /* erase (and check) old copy */
+      freeblock(mc, block, oldsize);  /* erase (and check) old copy */
     }
     /* initialize new part of the block with something `weird' */
     fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize);
-    memdebug_total += size;
-    if (memdebug_total > memdebug_maxmem)
-      memdebug_maxmem = memdebug_total;
-    memdebug_numblocks++;
+    mc->total += size;
+    if (mc->total > mc->maxmem)
+      mc->maxmem = mc->total;
+    mc->numblocks++;
     setsize(newblock, size);
     for (i=0;i<MARKSIZE;i++)
       *(cast(char *, newblock)+HEADER+size+i) = cast(char, MARK+i);
@@ -260,13 +257,13 @@ static int setgcthreshold (lua_State *L) {
 
 static int mem_query (lua_State *L) {
   if (lua_isnone(L, 1)) {
-    lua_pushintegral(L, memdebug_total);
-    lua_pushintegral(L, memdebug_numblocks);
-    lua_pushintegral(L, memdebug_maxmem);
+    lua_pushintegral(L, memcontrol.total);
+    lua_pushintegral(L, memcontrol.numblocks);
+    lua_pushintegral(L, memcontrol.maxmem);
     return 3;
   }
   else {
-    memdebug_memlimit = luaL_checkint(L, 1);
+    memcontrol.memlimit = luaL_checkint(L, 1);
     return 0;
   }
 }
@@ -830,8 +827,8 @@ static const struct luaL_reg tests_funcs[] = {
 static void fim (void) {
   if (!islocked)
     lua_close(lua_state);
-  lua_assert(memdebug_numblocks == 0);
-  lua_assert(memdebug_total == 0);
+  lua_assert(memcontrol.numblocks == 0);
+  lua_assert(memcontrol.total == 0);
 }
 
 
@@ -856,7 +853,7 @@ int luaB_opentests (lua_State *L) {
 int main (int argc, char *argv[]) {
   char *limit = getenv("MEMLIMIT");
   if (limit)
-    memdebug_memlimit = strtoul(limit, NULL, 10);
+    memcontrol.memlimit = strtoul(limit, NULL, 10);
   l_main(argc, argv);
   return 0;
 }

+ 12 - 8
ltests.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.h,v 1.19 2002/11/19 17:42:32 roberto Exp roberto $
+** $Id: ltests.h,v 1.20 2002/12/04 17:29:05 roberto Exp roberto $
 ** Internal Header for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -27,16 +27,20 @@
 
 
 /* memory allocator control variables */
-extern unsigned long memdebug_numblocks;
-extern unsigned long memdebug_total;
-extern unsigned long memdebug_maxmem;
-extern unsigned long memdebug_memlimit;
+typedef struct Memcontrol {
+  unsigned long numblocks;
+  unsigned long total;
+  unsigned long maxmem;
+  unsigned long memlimit;
+} Memcontrol;
 
+extern Memcontrol memcontrol;
 
-#define l_realloc(b, os, s)	debug_realloc(b, os, s)
-#define l_free(b, os)		debug_realloc(b, os, 0)
+void *debug_realloc (void *ud, void *block, size_t osize, size_t nsize);
 
-void *debug_realloc (void *block, size_t oldsize, size_t size);
+#ifdef lua_c
+#define luaL_newstate()	lua_newstate(debug_realloc, &memcontrol)
+#endif
 
 
 

+ 9 - 2
lua.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lua.h,v 1.177 2003/05/15 12:20:04 roberto Exp roberto $
+** $Id: lua.h,v 1.178 2003/07/07 13:30:57 roberto Exp roberto $
 ** Lua - An Extensible Extension Language
 ** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
 ** http://www.lua.org	mailto:[email protected]
@@ -56,6 +56,12 @@ typedef int (*lua_Chunkwriter) (lua_State *L, const void* p,
                                 size_t sz, void* ud);
 
 
+/*
+** prototype for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
 /*
 ** basic types
 */
@@ -101,7 +107,7 @@ typedef LUA_NUMBER lua_Number;
 /*
 ** state manipulation
 */
-LUA_API lua_State *lua_open (void);
+LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud);
 LUA_API void       lua_close (lua_State *L);
 LUA_API lua_State *lua_newthread (lua_State *L);
 
@@ -261,6 +267,7 @@ LUA_API void  lua_concat (lua_State *L, int n);
 ** compatibility macros and functions
 */
 
+#define lua_open()	luaL_newstate()
 
 #define lua_getregistry(L)	lua_pushvalue(L, LUA_REGISTRYINDEX)
 #define lua_setglobal(L,s)	\