3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5 M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6 P. Tomsich, J. Wenninger
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Reinhard Grafl
29 $Id: memory.c 557 2003-11-02 22:51:59Z twisti $
46 /********* general types, variables and auxiliary functions *********/
48 #define DUMPBLOCKSIZE (2<<21)
51 typedef struct dumplist {
52 struct dumplist *prev;
58 long int memoryusage = 0;
60 long int dumpsize = 0;
61 long int dumpspace = 0;
62 dumplist *topdumpblock = NULL;
64 long int maxmemusage = 0;
65 long int maxdumpsize = 0;
70 static char *nomallocmem = NULL;
71 static char *nomalloctop;
72 static char *nomallocptr;
75 static void *lit_checked_alloc (int length)
80 nomallocmem = malloc(16777216);
81 nomalloctop = nomallocmem + 16777216;
82 nomallocptr = nomallocmem;
85 nomallocptr = (void*) ALIGN ((long) nomallocptr, ALIGNSIZE);
88 nomallocptr += length;
89 if (nomallocptr > nomalloctop) panic ("Out of memory");
95 static void *lit_checked_alloc (int length)
97 void *m = malloc(length);
98 if (!m) panic ("Out of memory");
105 static void *checked_alloc (int length)
107 void *m = malloc(length);
108 if (!m) panic ("Out of memory");
113 static int mmapcodesize = 0;
114 static void *mmapcodeptr = NULL;
117 void *mem_mmap(int length)
121 length = (ALIGN(length,ALIGNSIZE));
122 if (length > mmapcodesize) {
123 mmapcodesize = 0x10000;
124 if (length > mmapcodesize)
125 mmapcodesize = length;
126 mmapcodesize = (ALIGN(mmapcodesize, getpagesize()));
127 mmapcodeptr = mmap (NULL, (size_t) mmapcodesize,
128 PROT_READ | PROT_WRITE | PROT_EXEC,
129 MAP_PRIVATE | MAP_ANONYMOUS, -1, (off_t) 0);
130 if (mmapcodeptr == (void*) -1)
131 panic ("Out of memory");
133 retptr = mmapcodeptr;
134 mmapcodeptr = (void*) ((char*) mmapcodeptr + length);
135 mmapcodesize -= length;
142 /************ Memory manager, safe version **************/
145 typedef struct memblock {
146 struct memblock *prev,*next;
150 #define BLOCKOFFSET (ALIGN(sizeof(memblock),ALIGNSIZE))
152 struct memblock *firstmemblock;
156 void *mem_alloc(int length)
160 if (length==0) return NULL;
161 mb = checked_alloc (length + BLOCKOFFSET);
164 mb -> next = firstmemblock;
165 mb -> length = length;
167 if (firstmemblock) firstmemblock -> prev = mb;
170 memoryusage += length;
171 if (memoryusage > maxmemusage) maxmemusage = memoryusage;
173 return ((char*) mb) + BLOCKOFFSET;
177 void *lit_mem_alloc(int length)
181 if (length==0) return NULL;
182 mb = lit_checked_alloc (length + BLOCKOFFSET);
185 mb -> next = firstmemblock;
186 mb -> length = length;
188 if (firstmemblock) firstmemblock -> prev = mb;
191 memoryusage += length;
192 if (memoryusage > maxmemusage) maxmemusage = memoryusage;
194 return ((char*) mb) + BLOCKOFFSET;
198 void mem_free(void *m, int length)
202 if (length==0) return;
203 panic ("returned memoryblock with address NULL, length != 0");
206 mb = (memblock*) (((char*) m) - BLOCKOFFSET);
208 if (mb->length != length) {
210 "Memory block of size %d has been return as size %d",
215 if (mb->prev) mb->prev->next = mb->next;
216 else firstmemblock = mb->next;
217 if (mb->next) mb->next->prev = mb->prev;
221 memoryusage -= length;
225 void lit_mem_free(void *m, int length)
229 if (length==0) return;
230 panic ("returned memoryblock with address NULL, length != 0");
233 mb = (memblock*) (((char*) m) - BLOCKOFFSET);
235 if (mb->length != length) {
237 "Memory block of size %d has been return as size %d",
242 if (mb->prev) mb->prev->next = mb->next;
243 else firstmemblock = mb->next;
244 if (mb->next) mb->next->prev = mb->prev;
251 memoryusage -= length;
255 void *mem_realloc (void *m1, int len1, int len2)
259 m2 = mem_alloc (len2);
260 memcpy (m2, m1, len1);
269 static void mem_characterlog (unsigned char *m, int len)
274 for (z=0; z<len; z+=LINESIZE) {
275 sprintf (logtext, " ");
277 for (i=z; i<(z+LINESIZE) && i<len; i++) {
278 sprintf (logtext+strlen(logtext), "%2x ", m[i]);
280 for (; i<(z+LINESIZE); i++) {
281 sprintf (logtext+strlen(logtext), " ");
284 sprintf (logtext+strlen(logtext)," ");
285 for (i=z; i<(z+LINESIZE) && i<len; i++) {
286 sprintf (logtext+strlen(logtext),
287 "%c", (m[i]>=' ' && m[i]<=127) ? m[i] : '.');
295 /******* Memory manager, fast version ******/
298 void *mem_alloc(int length)
300 if (length==0) return NULL;
302 memoryusage += length;
303 if (memoryusage > maxmemusage) maxmemusage = memoryusage;
305 return checked_alloc (length);
309 void *lit_mem_alloc(int length)
311 if (length==0) return NULL;
313 memoryusage += length;
314 if (memoryusage > maxmemusage) maxmemusage = memoryusage;
316 return lit_checked_alloc (length);
320 void mem_free(void *m, int length)
323 if (length==0) return;
324 panic ("returned memoryblock with address NULL, length != 0");
327 memoryusage -= length;
333 void lit_mem_free(void *m, int length)
336 if (length==0) return;
337 panic ("returned memoryblock with address NULL, length != 0");
340 memoryusage -= length;
349 void *mem_realloc (void *m1, int len1, int len2)
355 panic ("reallocating memoryblock with address NULL, length != 0");
358 memoryusage = (memoryusage - len1) + len2;
360 m2 = realloc (m1, len2);
361 if (!m2) panic ("Out of memory");
368 /******* common memory manager parts ******/
376 void *dump_alloc(int length)
380 if (length == 0) return NULL;
382 length = ALIGN(length, ALIGNSIZE);
384 assert(length <= DUMPBLOCKSIZE);
387 if (dumpsize + length > dumpspace) {
388 dumplist *newdumpblock = checked_alloc(sizeof(dumplist));
390 newdumpblock->prev = topdumpblock;
391 topdumpblock = newdumpblock;
393 newdumpblock->dumpmem = checked_alloc(DUMPBLOCKSIZE);
395 dumpsize = dumpspace;
396 dumpspace += DUMPBLOCKSIZE;
399 m = topdumpblock->dumpmem + DUMPBLOCKSIZE - (dumpspace - dumpsize);
402 if (dumpsize > maxdumpsize) {
403 maxdumpsize = dumpsize;
410 void *dump_realloc(void *ptr, int len1, int len2)
412 void *p2 = dump_alloc(len2);
413 memcpy(p2, ptr, len1);
424 void dump_release(long int size)
426 assert(size >= 0 && size <= dumpsize);
430 while (dumpspace > dumpsize + DUMPBLOCKSIZE) {
431 dumplist *oldtop = topdumpblock;
433 topdumpblock = oldtop->prev;
434 dumpspace -= DUMPBLOCKSIZE;
438 free(oldtop->dumpmem);
445 void mem_usagelog (int givewarnings)
447 if ((memoryusage!=0) && givewarnings) {
448 sprintf (logtext, "Allocated memory not returned: %d",
454 memblock *mb = firstmemblock;
456 sprintf (logtext, " Memory block size: %d",
459 mem_characterlog ( ((unsigned char*)mb) + BLOCKOFFSET, mb->length);
467 if ((dumpsize!=0) && givewarnings) {
468 sprintf (logtext, "Dump memory not returned: %d",(int)dumpsize);
473 sprintf(logtext, "Random/Dump - memory usage: %dK/%dK",
474 (int)((maxmemusage+1023)/1024),
475 (int)((maxdumpsize+1023)/1024) );
482 * These are local overrides for various environment variables in Emacs.
483 * Please do not remove this and leave it at the end of the file, where
484 * Emacs will automagically detect them.
485 * ---------------------------------------------------------------------
488 * indent-tabs-mode: t