aboutsummaryrefslogtreecommitdiff
path: root/lmem.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-12-28 10:55:41 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2000-12-28 10:55:41 -0200
commit0183b8030c80f57b87874ff7867ccdb172d9d3dc (patch)
tree1033b5a84489a2f1f1bd210b1b120155cd7aeed7 /lmem.c
parent8c49e198654567f770a7d5081b886a7c35201d81 (diff)
downloadlua-0183b8030c80f57b87874ff7867ccdb172d9d3dc.tar.gz
lua-0183b8030c80f57b87874ff7867ccdb172d9d3dc.tar.bz2
lua-0183b8030c80f57b87874ff7867ccdb172d9d3dc.zip
`free' gets size of the block: complete control over memory use
Diffstat (limited to 'lmem.c')
-rw-r--r--lmem.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/lmem.c b/lmem.c
index 830f6f1d..3d34e313 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.40 2000/11/24 17:39:56 roberto Exp roberto $ 2** $Id: lmem.c,v 1.41 2000/12/26 18:46:09 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*/
@@ -29,15 +29,14 @@
29#include <limits.h> 29#include <limits.h>
30#include <string.h> 30#include <string.h>
31 31
32#define realloc(b, s) debug_realloc(b, s) 32#define basicrealloc(b, os, s) debug_realloc(b, os, s)
33#define malloc(b) debug_realloc(NULL, b) 33#define basicfree(b, s) debug_realloc(b, s, 0)
34#define free(b) debug_realloc(b, 0)
35 34
36 35
37/* ensures maximum alignment for HEADER */ 36/* ensures maximum alignment for HEADER */
38#define HEADER (sizeof(union L_Umaxalign)) 37#define HEADER (sizeof(union L_Umaxalign))
39 38
40#define MARKSIZE 16 39#define MARKSIZE 32
41#define MARK 0x55 /* 01010101 (a nice pattern) */ 40#define MARK 0x55 /* 01010101 (a nice pattern) */
42 41
43 42
@@ -55,8 +54,6 @@ static void *checkblock (void *block) {
55 int i; 54 int i;
56 for (i=0;i<MARKSIZE;i++) 55 for (i=0;i<MARKSIZE;i++)
57 assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */ 56 assert(*(((char *)b)+HEADER+size+i) == MARK+i); /* corrupted block? */
58 memdebug_numblocks--;
59 memdebug_total -= size;
60 return b; 57 return b;
61} 58}
62 59
@@ -66,12 +63,15 @@ static void freeblock (void *block) {
66 size_t size = *blocksize(block); 63 size_t size = *blocksize(block);
67 block = checkblock(block); 64 block = checkblock(block);
68 memset(block, -1, size+HEADER+MARKSIZE); /* erase block */ 65 memset(block, -1, size+HEADER+MARKSIZE); /* erase block */
69 (free)(block); /* free original block */ 66 free(block); /* free original block */
67 memdebug_numblocks--;
68 memdebug_total -= size;
70 } 69 }
71} 70}
72 71
73 72
74static void *debug_realloc (void *block, size_t size) { 73static void *debug_realloc (void *block, size_t oldsize, size_t size) {
74 assert((oldsize == 0) ? block == NULL : oldsize == *blocksize(block));
75 if (size == 0) { 75 if (size == 0) {
76 freeblock(block); 76 freeblock(block);
77 return NULL; 77 return NULL;
@@ -79,19 +79,22 @@ static void *debug_realloc (void *block, size_t size) {
79 else if (memdebug_total+size > memdebug_memlimit) 79 else if (memdebug_total+size > memdebug_memlimit)
80 return NULL; /* to test memory allocation errors */ 80 return NULL; /* to test memory allocation errors */
81 else { 81 else {
82 size_t realsize = HEADER+size+MARKSIZE; 82 char *newblock;
83 char *newblock = (char *)(malloc)(realsize); /* alloc a new block */
84 int i; 83 int i;
84 size_t realsize = HEADER+size+MARKSIZE;
85 if (realsize < size) return NULL; /* overflow! */ 85 if (realsize < size) return NULL; /* overflow! */
86 newblock = (char *)malloc(realsize); /* alloc a new block */
86 if (newblock == NULL) return NULL; 87 if (newblock == NULL) return NULL;
88 if (oldsize > size) oldsize = size;
87 if (block) { 89 if (block) {
88 size_t oldsize = *blocksize(block);
89 if (oldsize > size) oldsize = size;
90 memcpy(newblock+HEADER, block, oldsize); 90 memcpy(newblock+HEADER, block, oldsize);
91 freeblock(block); /* erase (and check) old copy */ 91 freeblock(block); /* erase (and check) old copy */
92 } 92 }
93 /* initialize new part of the block with something `weird' */
94 memset(newblock+HEADER+oldsize, -MARK, size-oldsize);
93 memdebug_total += size; 95 memdebug_total += size;
94 if (memdebug_total > memdebug_maxmem) memdebug_maxmem = memdebug_total; 96 if (memdebug_total > memdebug_maxmem)
97 memdebug_maxmem = memdebug_total;
95 memdebug_numblocks++; 98 memdebug_numblocks++;
96 *(size_t *)newblock = size; 99 *(size_t *)newblock = size;
97 for (i=0;i<MARKSIZE;i++) 100 for (i=0;i<MARKSIZE;i++)
@@ -102,20 +105,26 @@ static void *debug_realloc (void *block, size_t size) {
102 105
103 106
104/* }====================================================================== */ 107/* }====================================================================== */
105#endif
106
107 108
109#else
110/* no debug */
108 111
109/* 112/*
110** Real ISO (ANSI) systems do not need these tests; 113** Real ISO (ANSI) systems do not need these tests;
111** but some systems (Sun OS) are not that ISO... 114** but some systems (Sun OS) are not that ISO...
112*/ 115*/
113#ifdef OLD_ANSI 116#ifdef OLD_ANSI
114#define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s)) 117#define basicrealloc(b,os,s) ((b) == NULL ? malloc(s) : realloc(b, s))
115#define free(b) if (b) (free)(b) 118#define basicfree(b,s) if (b) free(b)
119#else
120#define basicrealloc(b,os,s) realloc(b,s)
121#define basicfree(b,s) free(b)
122
116#endif 123#endif
117 124
118 125
126#endif
127
119void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems, 128void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
120 int limit, const char *errormsg) { 129 int limit, const char *errormsg) {
121 void *newblock; 130 void *newblock;
@@ -127,7 +136,8 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
127 newsize = limit; /* still have at least MINPOWER2 free places */ 136 newsize = limit; /* still have at least MINPOWER2 free places */
128 else lua_error(L, errormsg); 137 else lua_error(L, errormsg);
129 } 138 }
130 newblock = luaM_realloc(L, block, (luint32)newsize*(luint32)size_elems); 139 newblock = luaM_realloc(L, block, (luint32)(*size)*(luint32)size_elems,
140 (luint32)newsize*(luint32)size_elems);
131 *size = newsize; /* update only when everything else is OK */ 141 *size = newsize; /* update only when everything else is OK */
132 return newblock; 142 return newblock;
133} 143}
@@ -136,20 +146,25 @@ void *luaM_growaux (lua_State *L, void *block, int *size, int size_elems,
136/* 146/*
137** generic allocation routine. 147** generic allocation routine.
138*/ 148*/
139void *luaM_realloc (lua_State *L, void *block, luint32 size) { 149void *luaM_realloc (lua_State *L, void *block, luint32 oldsize, luint32 size) {
140 if (size == 0) { 150 if (size == 0) {
141 free(block); /* block may be NULL; that is OK for free */ 151 basicfree(block, oldsize); /* block may be NULL; that is OK for free */
142 return NULL; 152 block = NULL;
143 } 153 }
144 else if (size >= MAX_SIZET) 154 else if (size >= MAX_SIZET)
145 lua_error(L, "memory allocation error: block too big"); 155 lua_error(L, "memory allocation error: block too big");
146 block = realloc(block, size); 156 else {
147 if (block == NULL) { 157 block = basicrealloc(block, oldsize, size);
148 if (L) 158 if (block == NULL) {
149 luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */ 159 if (L)
150 else return NULL; /* error before creating state! */ 160 luaD_breakrun(L, LUA_ERRMEM); /* break run without error message */
161 else return NULL; /* error before creating state! */
162 }
163 }
164 if (L) {
165 L->nblocks -= oldsize;
166 L->nblocks += size;
151 } 167 }
152 return block; 168 return block;
153} 169}
154 170
155