From 973d81efb37d6d001cb10c987e0171e5500b9688 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 19 Apr 2010 13:38:25 -0300 Subject: complete control over number of each kind of object allocated --- ltests.c | 99 ++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 46 deletions(-) diff --git a/ltests.c b/ltests.c index da3aec94..ff0086a8 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.94 2010/04/13 20:48:12 roberto Exp roberto $ +** $Id: ltests.c,v 2.95 2010/04/16 17:42:49 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -74,90 +74,97 @@ static int tpanic (lua_State *L) { #define MARK 0x55 /* 01010101 (a nice pattern) */ +typedef union Header { + L_Umaxalign a; /* ensures maximum alignment for Header */ + struct { + size_t size; + int type; + } d; +} Header; + + #ifndef EXTERNMEMCHECK + /* full memory check */ -#define HEADER (sizeof(L_Umaxalign)) /* ensures maximum alignment for HEADER */ #define MARKSIZE 16 /* size of marks after each block */ -#define blockhead(b) (cast(char *, b) - HEADER) -#define setsize(newblock, size) (*cast(size_t *, newblock) = size) -#define checkblocksize(b, size) (size == (*cast(size_t *, blockhead(b)))) #define fillmem(mem,size) memset(mem, -MARK, size) + #else + /* external memory check: don't do it twice */ -#define HEADER 0 #define MARKSIZE 0 -#define blockhead(b) (b) -#define setsize(newblock, size) /* empty */ -#define checkblocksize(b,size) (1) #define fillmem(mem,size) /* empty */ + #endif + Memcontrol l_memcontrol = {0L, 0L, 0L, 0L, {0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L}}; -static void *checkblock (void *block, size_t size) { - void *b = blockhead(block); - int i; - for (i=0;inumblocks--; + size_t size = block->d.size; + int i; + for (i = 0; i < MARKSIZE; i++) /* check marks after block */ + lua_assert(*(cast(char *, block + 1) + size + i) == MARK); + mc->objcount[block->d.type]--; + fillmem(block, sizeof(Header) + size + MARKSIZE); /* erase block */ + free(block); /* actually free block */ + mc->numblocks--; /* update counts */ mc->total -= size; } } -void *debug_realloc (void *ud, void *block, size_t oldsize, size_t size) { +void *debug_realloc (void *ud, void *b, size_t oldsize, size_t size) { Memcontrol *mc = cast(Memcontrol *, ud); - if (block == NULL) { - if (oldsize < LUA_NUMTAGS) - mc->objcount[oldsize]++; - oldsize = 0; - } - lua_assert((oldsize == 0) ? block == NULL : - block && checkblocksize(block, oldsize)); + Header *block = cast(Header *, b); + int type; if (mc->memlimit == 0) { /* first time? */ char *limit = getenv("MEMLIMIT"); /* initialize memory limit */ mc->memlimit = limit ? strtoul(limit, NULL, 10) : ULONG_MAX; } + if (block == NULL) { + type = (oldsize < LUA_NUMTAGS) ? oldsize : 0; + oldsize = 0; + } + else { + block--; /* go to real header */ + type = block->d.type; + lua_assert(oldsize == block->d.size); + } if (size == 0) { - freeblock(mc, block, oldsize); + freeblock(mc, block); return NULL; } else if (size > oldsize && mc->total+size-oldsize > mc->memlimit) - return NULL; /* to test memory allocation errors */ + return NULL; /* fake a memory allocation error */ else { - void *newblock; + Header *newblock; int i; - size_t realsize = HEADER+size+MARKSIZE; size_t commonsize = (oldsize < size) ? oldsize : size; - if (realsize < size) return NULL; /* overflow! */ - newblock = malloc(realsize); /* alloc a new block */ - if (newblock == NULL) return NULL; + size_t realsize = sizeof(Header) + size + MARKSIZE; + if (realsize < size) return NULL; /* arithmetic overflow! */ + newblock = cast(Header *, malloc(realsize)); /* alloc a new block */ + if (newblock == NULL) return NULL; /* really out of memory? */ if (block) { - memcpy(cast(char *, newblock)+HEADER, block, commonsize); - freeblock(mc, block, oldsize); /* erase (and check) old copy */ + memcpy(newblock + 1, block + 1, commonsize); /* copy old contents */ + freeblock(mc, block); /* erase (and check) old copy */ } /* initialize new part of the block with something `weird' */ - fillmem(cast(char *, newblock)+HEADER+commonsize, size-commonsize); + fillmem(cast(char *, newblock + 1) + commonsize, size - commonsize); + /* initialize marks after block */ + for (i = 0; i < MARKSIZE; i++) + *(cast(char *, newblock + 1) + size + i) = MARK; + newblock->d.size = size; + newblock->d.type = type; mc->total += size; if (mc->total > mc->maxmem) mc->maxmem = mc->total; mc->numblocks++; - setsize(newblock, size); - for (i=0;iobjcount[type]++; + return newblock + 1; } } -- cgit v1.2.3-55-g6feb