2 ** $Id: lmem.c,v 1.17 1999/05/24 17:51:05 roberto Exp $
3 ** Interface to Memory Manager
4 ** See Copyright Notice in lua.h
16 ** real ANSI systems do not need these tests;
17 ** but some systems (Sun OS) are not that ANSI...
20 #define realloc(b,s) ((b) == NULL ? malloc(s) : (realloc)(b, s))
21 #define free(b) if (b) (free)(b)
25 #define MINSIZE 8 /* minimum size for "growing" vectors */
30 static unsigned long power2 (unsigned long n
) {
31 unsigned long p
= MINSIZE
;
37 void *luaM_growaux (void *block
, unsigned long nelems
, int inc
, int size
,
38 char *errormsg
, unsigned long limit
) {
39 unsigned long newn
= nelems
+inc
;
40 if (newn
>= limit
) lua_error(errormsg
);
41 if ((newn
^ nelems
) <= nelems
|| /* still the same power of 2 limit? */
42 (nelems
> 0 && newn
< MINSIZE
)) /* or block already is MINSIZE? */
43 return block
; /* do not need to reallocate */
44 else /* it crossed a power of 2 boundary; grow to next power */
45 return luaM_realloc(block
, power2(newn
)*size
);
52 ** generic allocation routine.
54 void *luaM_realloc (void *block
, unsigned long size
) {
55 size_t s
= (size_t)size
;
57 lua_error("memory allocation error: block too big");
59 free(block
); /* block may be NULL, that is OK for free */
62 block
= realloc(block
, s
);
76 #define HEADER (sizeof(double))
82 #define blocksize(b) ((unsigned long *)((char *)(b) - HEADER))
84 unsigned long numblocks
= 0;
85 unsigned long totalmem
= 0;
88 static void *checkblock (void *block
) {
92 unsigned long *b
= blocksize(block
);
93 unsigned long size
= *b
;
95 for (i
=0;i
<MARKSIZE
;i
++)
96 LUA_ASSERT(*(((char *)b
)+HEADER
+size
+i
) == MARK
+i
, "corrupted block");
104 static void freeblock (void *block
) {
106 memset(block
, -1, *blocksize(block
)); /* erase block */
107 free(checkblock(block
));
111 void *luaM_realloc (void *block
, unsigned long size
) {
112 unsigned long realsize
= HEADER
+size
+MARKSIZE
;
113 if (realsize
!= (size_t)realsize
)
114 lua_error("memory allocation error: block too big");
120 char *newblock
= malloc(realsize
);
123 unsigned long oldsize
= *blocksize(block
);
124 if (oldsize
> size
) oldsize
= size
;
125 memcpy(newblock
+HEADER
, block
, oldsize
);
126 freeblock(block
); /* erase (and check) old copy */
128 if (newblock
== NULL
)
132 *(unsigned long *)newblock
= size
;
133 for (i
=0;i
<MARKSIZE
;i
++)
134 *(newblock
+HEADER
+size
+i
) = MARK
+i
;
135 return newblock
+HEADER
;