3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
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 Changes: Christian Thalinger
31 $Id: memory.c 3403 2005-10-12 08:17:00Z twisti $
41 #if defined(__DARWIN__)
42 /* If we compile with -ansi on darwin, <sys/types.h> is not included. So */
43 /* let's do it here. */
44 # include <sys/types.h>
52 #include "mm/memory.h"
53 #include "native/native.h"
55 #if defined(USE_THREADS)
56 # if defined(NATIVE_THREADS)
57 # include "threads/native/threads.h"
59 # include "threads/green/threads.h"
63 #include "toolbox/logging.h"
64 #include "vm/exceptions.h"
65 #include "vm/global.h"
66 #include "vm/options.h"
67 #include "vm/statistics.h"
68 #include "vm/stringlocal.h"
71 /*******************************************************************************
73 This structure is used for dump memory allocation if cacao
76 *******************************************************************************/
78 #if !defined(USE_THREADS) || (defined(USE_THREADS) && !defined(NATIVE_THREADS))
79 static dumpinfo _no_threads_dumpinfo;
82 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
83 #define DUMPINFO &((threadobject *) THREADOBJECT)->dumpinfo
85 #define DUMPINFO &_no_threads_dumpinfo
89 static void *checked_alloc(s4 size)
91 /* always allocate memory zeroed out */
92 void *m = calloc(size, 1);
95 throw_cacao_exception_exit(string_java_lang_InternalError,
102 void *mem_alloc(s4 size)
107 #if defined(STATISTICS)
111 if (memoryusage > maxmemusage)
112 maxmemusage = memoryusage;
116 return checked_alloc(size);
120 void *mem_realloc(void *src, s4 len1, s4 len2)
126 log_text("reallocating memoryblock with address NULL, length != 0");
131 #if defined(STATISTICS)
133 memoryusage = (memoryusage - len1) + len2;
136 dst = realloc(src, len2);
139 throw_cacao_exception_exit(string_java_lang_InternalError,
146 void mem_free(void *m, s4 size)
152 log_text("returned memoryblock with address NULL, length != 0");
156 #if defined(STATISTICS)
165 /* dump_alloc ******************************************************************
169 *******************************************************************************/
171 void *dump_alloc(s4 size)
173 #if defined(DISABLE_DUMP)
174 /* use malloc memory for dump memory (for debugging only!) */
176 return mem_alloc(size);
181 /* If no threads are used, the dumpinfo structure is a static structure */
182 /* defined at the top of this file. */
189 size = ALIGN(size, ALIGNSIZE);
191 if (di->useddumpsize + size > di->allocateddumpsize) {
192 dumpblock *newdumpblock;
195 /* allocate a new dumplist structure */
197 newdumpblock = checked_alloc(sizeof(dumpblock));
199 /* If requested size is greater than the default, make the new dump */
200 /* block as big as the size requested. Else use the default size. */
202 if (size > DUMPBLOCKSIZE) {
203 newdumpblocksize = size;
206 newdumpblocksize = DUMPBLOCKSIZE;
209 /* allocate dumpblock memory */
211 newdumpblock->dumpmem = checked_alloc(newdumpblocksize);
213 newdumpblock->prev = di->currentdumpblock;
214 newdumpblock->size = newdumpblocksize;
215 di->currentdumpblock = newdumpblock;
217 /* Used dump size is previously allocated dump size, because the */
218 /* remaining free memory of the previous dump block cannot be used. */
220 di->useddumpsize = di->allocateddumpsize;
222 /* increase the allocated dump size by the size of the new dump block */
224 di->allocateddumpsize += newdumpblocksize;
226 #if defined(STATISTICS)
227 /* the amount of globally allocated dump memory (thread save) */
230 globalallocateddumpsize += newdumpblocksize;
234 /* current dump block base address + the size of the current dump block - */
235 /* the size of the unused memory = new start address */
237 m = di->currentdumpblock->dumpmem + di->currentdumpblock->size -
238 (di->allocateddumpsize - di->useddumpsize);
240 /* increase used dump size by the allocated memory size */
242 di->useddumpsize += size;
244 #if defined(STATISTICS)
246 if (di->useddumpsize > maxdumpsize)
247 maxdumpsize = di->useddumpsize;
251 #endif /* defined(DISABLE_DUMP) */
255 /* dump_realloc ****************************************************************
259 *******************************************************************************/
261 void *dump_realloc(void *src, s4 len1, s4 len2)
263 #if defined(DISABLE_DUMP)
264 /* use malloc memory for dump memory (for debugging only!) */
266 return mem_realloc(src, len1, len2);
268 void *dst = dump_alloc(len2);
270 memcpy(dst, src, len1);
277 /* dump_release ****************************************************************
281 *******************************************************************************/
283 void dump_release(s4 size)
285 #if defined(DISABLE_DUMP)
286 /* use malloc memory for dump memory (for debugging only!) */
292 /* If no threads are used, the dumpinfo structure is a static structure */
293 /* defined at the top of this file. */
297 if (size < 0 || size > di->useddumpsize)
298 throw_cacao_exception_exit(string_java_lang_InternalError,
299 "Illegal dump release size %d", size);
301 /* reset the used dump size to the size specified */
303 di->useddumpsize = size;
305 while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) {
306 dumpblock *tmp = di->currentdumpblock;
309 /* XXX TWISTI: can someone explain this to me? */
311 /* Keep the first dumpblock if we don't free memory. Otherwise
312 * a new dumpblock is allocated each time and we run out of
315 if (!oldtop->prev) break;
319 di->allocateddumpsize -= tmp->size;
320 di->currentdumpblock = tmp->prev;
322 #if defined(STATISTICS)
323 /* the amount of globally allocated dump memory (thread save) */
326 globalallocateddumpsize -= tmp->size;
329 /* release the dump memory and the dumpinfo structure */
334 #endif /* defined(DISABLE_DUMP) */
338 /* dump_size *******************************************************************
342 *******************************************************************************/
346 #if defined(DISABLE_DUMP)
347 /* use malloc memory for dump memory (for debugging only!) */
353 /* If no threads are used, the dumpinfo structure is a static structure */
354 /* defined at the top of this file. */
361 return di->useddumpsize;
362 #endif /* defined(DISABLE_DUMP) */
367 * These are local overrides for various environment variables in Emacs.
368 * Please do not remove this and leave it at the end of the file, where
369 * Emacs will automagically detect them.
370 * ---------------------------------------------------------------------
373 * indent-tabs-mode: t