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 1335 2004-07-21 15:57:10Z twisti $
41 #include "exceptions.h"
44 #include "toolbox/logging.h"
45 #include "toolbox/memory.h"
48 /********* general types, variables and auxiliary functions *********/
50 #define DUMPBLOCKSIZE (2<<21)
53 typedef struct dumplist {
54 struct dumplist *prev;
60 static int mmapcodesize = 0;
61 static void *mmapcodeptr = NULL;
63 long int memoryusage = 0;
65 long int dumpsize = 0;
66 long int dumpspace = 0;
67 dumplist *topdumpblock = NULL;
69 long int maxmemusage = 0;
70 long int maxdumpsize = 0;
73 static void *lit_checked_alloc(int length)
75 void *m = malloc(length);
78 throw_cacao_exception_exit(string_java_lang_InternalError,
81 /* not setting to zero causes cacao to segfault (String.hashCode() is
89 static void *checked_alloc(int length)
91 void *m = malloc(length);
94 throw_cacao_exception_exit(string_java_lang_InternalError,
101 void *mem_mmap(int length)
105 length = ALIGN(length, ALIGNSIZE);
107 if (length > mmapcodesize) {
108 mmapcodesize = 0x10000;
110 if (length > mmapcodesize)
111 mmapcodesize = length;
113 mmapcodesize = ALIGN(mmapcodesize, getpagesize());
114 mmapcodeptr = mmap (NULL,
115 (size_t) mmapcodesize,
116 PROT_READ | PROT_WRITE | PROT_EXEC,
117 MAP_PRIVATE | MAP_ANONYMOUS,
121 if (mmapcodeptr == MAP_FAILED)
122 throw_cacao_exception_exit(string_java_lang_InternalError,
126 retptr = mmapcodeptr;
127 mmapcodeptr = (void *) ((char *) mmapcodeptr + length);
128 mmapcodesize -= length;
134 void *mem_alloc(int length)
139 memoryusage += length;
140 if (memoryusage > maxmemusage)
141 maxmemusage = memoryusage;
143 return checked_alloc(length);
147 void *lit_mem_alloc(int length)
152 memoryusage += length;
153 if (memoryusage > maxmemusage)
154 maxmemusage = memoryusage;
156 return lit_checked_alloc(length);
160 void mem_free(void *m, int length)
165 panic("returned memoryblock with address NULL, length != 0");
168 memoryusage -= length;
174 void lit_mem_free(void *m, int length)
179 panic("returned memoryblock with address NULL, length != 0");
182 memoryusage -= length;
188 void *mem_realloc(void *m1, int len1, int len2)
194 panic("reallocating memoryblock with address NULL, length != 0");
197 memoryusage = (memoryusage - len1) + len2;
199 m2 = realloc(m1, len2);
202 throw_cacao_exception_exit(string_java_lang_InternalError,
209 /******* common memory manager parts ******/
217 void *dump_alloc(int length)
220 return checked_alloc(length);
223 int blocksize = DUMPBLOCKSIZE;
225 if (length == 0) return NULL;
227 length = ALIGN(length, ALIGNSIZE);
229 if (length > DUMPBLOCKSIZE)
233 if (dumpsize + length > dumpspace) {
234 dumplist *newdumpblock = checked_alloc(sizeof(dumplist));
236 newdumpblock->prev = topdumpblock;
237 newdumpblock->size = blocksize;
238 topdumpblock = newdumpblock;
240 newdumpblock->dumpmem = checked_alloc(blocksize);
242 dumpsize = dumpspace;
243 dumpspace += blocksize;
246 m = topdumpblock->dumpmem + blocksize - (dumpspace - dumpsize);
249 if (dumpsize > maxdumpsize) {
250 maxdumpsize = dumpsize;
258 void *dump_realloc(void *ptr, int len1, int len2)
260 void *p2 = dump_alloc(len2);
262 memcpy(p2, ptr, len1);
274 void dump_release(long int size)
277 assert(size >= 0 && size <= dumpsize);
281 while (topdumpblock && (dumpspace - topdumpblock->size >= dumpsize)) {
282 dumplist *oldtop = topdumpblock;
285 /* Keep the first dumpblock if we don't free memory. Otherwise
286 * a new dumpblock is allocated each time and we run out of
289 if (!oldtop->prev) break;
292 dumpspace -= oldtop->size;
293 topdumpblock = oldtop->prev;
295 free(oldtop->dumpmem);
301 void mem_usagelog (int givewarnings)
303 if ((memoryusage != 0) && givewarnings) {
304 dolog("Allocated memory not returned: %d", (s4) memoryusage);
307 if ((dumpsize != 0) && givewarnings) {
308 dolog("Dump memory not returned: %d", (s4) dumpsize);
311 dolog("Random/Dump - memory usage: %dK/%dK",
312 (s4) ((maxmemusage + 1023) / 1024),
313 (s4) ((maxdumpsize + 1023) / 1024));
318 * These are local overrides for various environment variables in Emacs.
319 * Please do not remove this and leave it at the end of the file, where
320 * Emacs will automagically detect them.
321 * ---------------------------------------------------------------------
324 * indent-tabs-mode: t