diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-01-13 14:30:47 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-01-13 14:30:47 -0200 |
| commit | ea45f3eb284e86354f19536b22a49b61f1800cc3 (patch) | |
| tree | 6bfa61df7bafdd84f5448b6fc6d66146d961f556 | |
| parent | 46ec57cbc6dfe8df707be8f1fa52146988013feb (diff) | |
| download | lua-ea45f3eb284e86354f19536b22a49b61f1800cc3.tar.gz lua-ea45f3eb284e86354f19536b22a49b61f1800cc3.tar.bz2 lua-ea45f3eb284e86354f19536b22a49b61f1800cc3.zip | |
better separation between debug code and regular code
| -rw-r--r-- | lmem.c | 114 |
1 files changed, 61 insertions, 53 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lmem.c,v 1.22 1999/12/14 18:31:20 roberto Exp roberto $ | 2 | ** $Id: lmem.c,v 1.23 1999/12/27 17:33:22 roberto Exp roberto $ |
| 3 | ** Interface to Memory Manager | 3 | ** Interface to Memory Manager |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,56 +26,32 @@ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | 29 | #ifdef DEBUG | |
| 30 | void *luaM_growaux (lua_State *L, void *block, unsigned long nelems, | ||
| 31 | int inc, int size, const char *errormsg, unsigned long limit) { | ||
| 32 | unsigned long newn = nelems+inc; | ||
| 33 | if (newn >= limit) lua_error(L, errormsg); | ||
| 34 | if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */ | ||
| 35 | (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */ | ||
| 36 | return block; /* do not need to reallocate */ | ||
| 37 | else /* it crossed a power-of-2 boundary; grow to next power */ | ||
| 38 | return luaM_realloc(L, block, luaO_power2(newn)*size); | ||
| 39 | } | ||
| 40 | |||
| 41 | |||
| 42 | #ifndef DEBUG | ||
| 43 | |||
| 44 | /* | 30 | /* |
| 45 | ** generic allocation routine. | 31 | ** {====================================================================== |
| 32 | ** Controled version for realloc. | ||
| 33 | ** ======================================================================= | ||
| 46 | */ | 34 | */ |
| 47 | void *luaM_realloc (lua_State *L, void *block, unsigned long size) { | ||
| 48 | size_t s = (size_t)size; | ||
| 49 | if (s != size) | ||
| 50 | lua_error(L, "memory allocation error: block too big"); | ||
| 51 | if (size == 0) { | ||
| 52 | free(block); /* block may be NULL; that is OK for free */ | ||
| 53 | return NULL; | ||
| 54 | } | ||
| 55 | block = realloc(block, s); | ||
| 56 | if (block == NULL) | ||
| 57 | lua_error(L, memEM); | ||
| 58 | return block; | ||
| 59 | } | ||
| 60 | 35 | ||
| 61 | 36 | ||
| 37 | #include <assert.h> | ||
| 38 | #include <string.h> | ||
| 62 | 39 | ||
| 63 | #else | ||
| 64 | /* DEBUG */ | ||
| 65 | 40 | ||
| 66 | #include <string.h> | 41 | #define realloc(b, s) debug_realloc(b, s) |
| 42 | #define malloc(b) debug_realloc(NULL, 0) | ||
| 43 | #define free(b) debug_realloc(b, 0) | ||
| 67 | 44 | ||
| 68 | 45 | ||
| 69 | #define HEADER (sizeof(double)) | 46 | #define HEADER (sizeof(double)) /* maximum alignment */ |
| 70 | #define MARKSIZE 16 | 47 | #define MARKSIZE 16 |
| 71 | 48 | #define MARK 0x55 /* 01010101 (a nice pattern) */ | |
| 72 | #define MARK 55 | ||
| 73 | 49 | ||
| 74 | 50 | ||
| 75 | #define blocksize(b) ((unsigned long *)((char *)(b) - HEADER)) | 51 | #define blocksize(b) ((unsigned long *)((char *)(b) - HEADER)) |
| 76 | 52 | ||
| 77 | unsigned long numblocks = 0; | 53 | unsigned long memdebug_numblocks = 0; |
| 78 | unsigned long totalmem = 0; | 54 | unsigned long memdebug_total = 0; |
| 79 | 55 | ||
| 80 | 56 | ||
| 81 | static void *checkblock (void *block) { | 57 | static void *checkblock (void *block) { |
| @@ -83,43 +59,41 @@ static void *checkblock (void *block) { | |||
| 83 | unsigned long size = *b; | 59 | unsigned long size = *b; |
| 84 | int i; | 60 | int i; |
| 85 | for (i=0;i<MARKSIZE;i++) | 61 | for (i=0;i<MARKSIZE;i++) |
| 86 | LUA_ASSERT(L, *(((char *)b)+HEADER+size+i) == MARK+i, "corrupted block"); | 62 | assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */ |
| 87 | numblocks--; | 63 | memdebug_numblocks--; |
| 88 | totalmem -= size; | 64 | memdebug_total -= size; |
| 89 | return b; | 65 | return b; |
| 90 | } | 66 | } |
| 91 | 67 | ||
| 92 | 68 | ||
| 93 | static void freeblock (void *block) { | 69 | static void freeblock (void *block) { |
| 94 | if (block) { | 70 | if (block) { |
| 95 | memset(block, -1, *blocksize(block)); /* erase block */ | 71 | size_t size = *blocksize(block); |
| 96 | block = checkblock(block); | 72 | block = checkblock(block); |
| 97 | free(block); | 73 | memset(block, -1, size+HEADER+MARKSIZE); /* erase block */ |
| 74 | (free)(block); /* free original block */ | ||
| 98 | } | 75 | } |
| 99 | } | 76 | } |
| 100 | 77 | ||
| 101 | 78 | ||
| 102 | void *luaM_realloc (lua_State *L, void *block, unsigned long size) { | 79 | static void *debug_realloc (void *block, size_t size) { |
| 103 | unsigned long realsize = HEADER+size+MARKSIZE; | 80 | size_t realsize = HEADER+size+MARKSIZE; |
| 104 | if (realsize != (size_t)realsize) | ||
| 105 | lua_error(L, "memory allocation error: block too big"); | ||
| 106 | if (size == 0) { | 81 | if (size == 0) { |
| 107 | freeblock(block); | 82 | freeblock(block); |
| 108 | return NULL; | 83 | return NULL; |
| 109 | } | 84 | } |
| 110 | else { | 85 | else { |
| 111 | char *newblock = malloc(realsize); | 86 | char *newblock = (malloc)(realsize); /* alloc a new block */ |
| 112 | int i; | 87 | int i; |
| 113 | if (block) { | 88 | if (block) { |
| 114 | unsigned long oldsize = *blocksize(block); | 89 | size_t oldsize = *blocksize(block); |
| 115 | if (oldsize > size) oldsize = size; | 90 | if (oldsize > size) oldsize = size; |
| 116 | memcpy(newblock+HEADER, block, oldsize); | 91 | memcpy(newblock+HEADER, block, oldsize); |
| 117 | freeblock(block); /* erase (and check) old copy */ | 92 | freeblock(block); /* erase (and check) old copy */ |
| 118 | } | 93 | } |
| 119 | if (newblock == NULL) | 94 | if (newblock == NULL) return NULL; |
| 120 | lua_error(L, memEM); | 95 | memdebug_total += size; |
| 121 | totalmem += size; | 96 | memdebug_numblocks++; |
| 122 | numblocks++; | ||
| 123 | *(unsigned long *)newblock = size; | 97 | *(unsigned long *)newblock = size; |
| 124 | for (i=0;i<MARKSIZE;i++) | 98 | for (i=0;i<MARKSIZE;i++) |
| 125 | *(newblock+HEADER+size+i) = (char)(MARK+i); | 99 | *(newblock+HEADER+size+i) = (char)(MARK+i); |
| @@ -128,4 +102,38 @@ void *luaM_realloc (lua_State *L, void *block, unsigned long size) { | |||
| 128 | } | 102 | } |
| 129 | 103 | ||
| 130 | 104 | ||
| 105 | /* }====================================================================== */ | ||
| 131 | #endif | 106 | #endif |
| 107 | |||
| 108 | |||
| 109 | |||
| 110 | void *luaM_growaux (lua_State *L, void *block, unsigned long nelems, | ||
| 111 | int inc, int size, const char *errormsg, unsigned long limit) { | ||
| 112 | unsigned long newn = nelems+inc; | ||
| 113 | if (newn >= limit) lua_error(L, errormsg); | ||
| 114 | if ((newn ^ nelems) <= nelems || /* still the same power-of-2 limit? */ | ||
| 115 | (nelems > 0 && newn < MINPOWER2)) /* or block already is MINPOWER2? */ | ||
| 116 | return block; /* do not need to reallocate */ | ||
| 117 | else /* it crossed a power-of-2 boundary; grow to next power */ | ||
| 118 | return luaM_realloc(L, block, luaO_power2(newn)*size); | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | /* | ||
| 123 | ** generic allocation routine. | ||
| 124 | */ | ||
| 125 | void *luaM_realloc (lua_State *L, void *block, unsigned long size) { | ||
| 126 | size_t s = (size_t)size; | ||
| 127 | if (s != size) | ||
| 128 | lua_error(L, "memory allocation error: block too big"); | ||
| 129 | if (size == 0) { | ||
| 130 | free(block); /* block may be NULL; that is OK for free */ | ||
| 131 | return NULL; | ||
| 132 | } | ||
| 133 | block = realloc(block, s); | ||
| 134 | if (block == NULL) | ||
| 135 | lua_error(L, memEM); | ||
| 136 | return block; | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
