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 1437 2004-11-05 09:51:07Z twisti $
41 #include "exceptions.h"
45 #include "statistics.h"
46 #include "threads/nativethread.h"
47 #include "toolbox/logging.h"
48 #include "toolbox/memory.h"
51 /********* general types, variables and auxiliary functions *********/
53 static int mmapcodesize = 0;
54 static void *mmapcodeptr = NULL;
57 /*******************************************************************************
59 This structure is used for dump memory allocation if cacao runs without
62 *******************************************************************************/
64 #if !defined(USE_THREADS)
65 static dumpinfo nothreads_dumpinfo;
69 void *mem_mmap(int size)
73 size = ALIGN(size, ALIGNSIZE);
75 if (size > mmapcodesize) {
76 mmapcodesize = 0x10000;
78 if (size > mmapcodesize)
81 mmapcodesize = ALIGN(mmapcodesize, getpagesize());
82 mmapcodeptr = mmap(NULL,
83 (size_t) mmapcodesize,
84 PROT_READ | PROT_WRITE | PROT_EXEC,
85 MAP_PRIVATE | MAP_ANONYMOUS,
89 if (mmapcodeptr == MAP_FAILED)
90 throw_cacao_exception_exit(string_java_lang_InternalError,
95 mmapcodeptr = (void *) ((char *) mmapcodeptr + size);
102 static void *checked_alloc(int size)
104 /* always allocate memory zeroed out */
105 void *m = calloc(size, 1);
108 throw_cacao_exception_exit(string_java_lang_InternalError,
115 void *mem_alloc(int size)
123 if (memoryusage > maxmemusage)
124 maxmemusage = memoryusage;
127 return checked_alloc(size);
131 void *mem_realloc(void *src, int len1, int len2)
137 panic("reallocating memoryblock with address NULL, length != 0");
141 memoryusage = (memoryusage - len1) + len2;
143 dst = realloc(src, len2);
146 throw_cacao_exception_exit(string_java_lang_InternalError,
153 void mem_free(void *m, int size)
158 panic("returned memoryblock with address NULL, length != 0");
168 void *dump_alloc(int size)
173 /* If no threads are used, the dumpinfo structure is a static structure */
174 /* defined at the top of this file. */
175 #if defined(USE_THREADS)
176 di = &((threadobject *) THREADOBJECT)->dumpinfo;
178 di = ¬hreads_dumpinfo;
184 size = ALIGN(size, ALIGNSIZE);
186 if (di->useddumpsize + size > di->allocateddumpsize) {
187 dumpblock *newdumpblock;
190 /* allocate a new dumplist structure */
191 newdumpblock = checked_alloc(sizeof(dumpblock));
193 /* If requested size is greater than the default, make the new dump */
194 /* block as big as the size requested. Else use the default size. */
195 if (size > DUMPBLOCKSIZE) {
196 newdumpblocksize = size;
199 newdumpblocksize = DUMPBLOCKSIZE;
202 /* allocate dumpblock memory */
203 //printf("new dumpblock: %d\n", newdumpblocksize);
204 newdumpblock->dumpmem = checked_alloc(newdumpblocksize);
206 newdumpblock->prev = di->currentdumpblock;
207 newdumpblock->size = newdumpblocksize;
208 di->currentdumpblock = newdumpblock;
210 /* Used dump size is previously allocated dump size, because the */
211 /* remaining free memory of the previous dump block cannot be used. */
212 //printf("unused memory: %d\n", allocateddumpsize - useddumpsize);
213 di->useddumpsize = di->allocateddumpsize;
215 /* increase the allocated dump size by the size of the new dump block */
216 di->allocateddumpsize += newdumpblocksize;
218 /* the amount of globally allocated dump memory (thread save) */
220 globalallocateddumpsize += newdumpblocksize;
223 /* current dump block base address + the size of the current dump block - */
224 /* the size of the unused memory = new start address */
225 m = di->currentdumpblock->dumpmem + di->currentdumpblock->size -
226 (di->allocateddumpsize - di->useddumpsize);
228 /* increase used dump size by the allocated memory size */
229 di->useddumpsize += size;
232 if (di->useddumpsize > maxdumpsize) {
233 maxdumpsize = di->useddumpsize;
241 void *dump_realloc(void *src, int len1, int len2)
243 void *dst = dump_alloc(len2);
245 memcpy(dst, src, len1);
251 void dump_release(int size)
255 /* If no threads are used, the dumpinfo structure is a static structure */
256 /* defined at the top of this file. */
257 #if defined(USE_THREADS)
258 di = &((threadobject *) THREADOBJECT)->dumpinfo;
260 di = ¬hreads_dumpinfo;
263 if (size < 0 || size > di->useddumpsize)
264 throw_cacao_exception_exit(string_java_lang_InternalError,
265 "Illegal dump release size %d", size);
267 /* reset the used dump size to the size specified */
268 di->useddumpsize = size;
270 while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) {
271 dumpblock *tmp = di->currentdumpblock;
274 /* XXX TWISTI: can someone explain this to me? */
276 /* Keep the first dumpblock if we don't free memory. Otherwise
277 * a new dumpblock is allocated each time and we run out of
280 if (!oldtop->prev) break;
284 di->allocateddumpsize -= tmp->size;
285 di->currentdumpblock = tmp->prev;
287 /* the amount of globally allocated dump memory (thread save) */
289 globalallocateddumpsize -= tmp->size;
291 /* release the dump memory and the dumpinfo structure */
302 /* If no threads are used, the dumpinfo structure is a static structure */
303 /* defined at the top of this file. */
304 #if defined(USE_THREADS)
305 di = &((threadobject *) THREADOBJECT)->dumpinfo;
307 di = ¬hreads_dumpinfo;
310 return di->useddumpsize;
315 * These are local overrides for various environment variables in Emacs.
316 * Please do not remove this and leave it at the end of the file, where
317 * Emacs will automagically detect them.
318 * ---------------------------------------------------------------------
321 * indent-tabs-mode: t