X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fmm%2Fmemory.c;h=80951ee5e6e34f13bf88ea66b40586786d2385c9;hb=2f22fef9e8f80103c54b2bd06492340a4447a2af;hp=7b2d97812931feec1ef7c0941e57988f1b72b1df;hpb=5dd21fcc60393421204036200d1fffc5218a2e17;p=cacao.git diff --git a/src/mm/memory.c b/src/mm/memory.c index 7b2d97812..80951ee5e 100644 --- a/src/mm/memory.c +++ b/src/mm/memory.c @@ -1,9 +1,7 @@ /* src/mm/memory.c - memory management - Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel, - C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, - E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, - J. Wenninger, Institut f. Computersprachen - TU Wien + Copyright (C) 1996-2005, 2006, 2007, 2008 + CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO This file is part of CACAO. @@ -33,7 +31,6 @@ #include #include #include -#include #if defined(__DARWIN__) /* If we compile with -ansi on darwin, is not @@ -50,14 +47,14 @@ #include "native/native.h" #include "threads/lock-common.h" -#include "threads/threads-common.h" +#include "threads/thread.h" #include "toolbox/logging.h" #include "vm/exceptions.h" #include "vm/global.h" #include "vm/stringlocal.h" -#include "vm/vm.h" +#include "vm/vm.hpp" #include "vmcore/options.h" @@ -65,101 +62,21 @@ # include "vmcore/statistics.h" #endif +#include "vmcore/system.h" -/******************************************************************************* - This structure is used for dump memory allocation if cacao - runs without threads. +/* memory_mprotect ************************************************************* -*******************************************************************************/ - -#if !defined(ENABLE_THREADS) -static dumpinfo_t _no_threads_dumpinfo; -#endif - -#if defined(ENABLE_THREADS) -#define DUMPINFO &((threadobject *) THREADOBJECT)->dumpinfo -#else -#define DUMPINFO &_no_threads_dumpinfo -#endif - - -/* global code memory variables ***********************************************/ - -#define DEFAULT_CODE_MEMORY_SIZE 128 * 1024 /* defaulting to 128kB */ - -#if defined(ENABLE_THREADS) -static java_object_t *lock_code_memory = NULL; -#endif -static void *code_memory = NULL; -static int code_memory_size = 0; -static int pagesize = 0; - - -/* memory_init ***************************************************************** - - Initialize the memory subsystem. - -*******************************************************************************/ - -bool memory_init(void) -{ -#if defined(ENABLE_THREADS) - /* create lock for code memory */ - - lock_code_memory = NEW(java_object_t); - - lock_init_object_lock(lock_code_memory); -#endif - - /* get the pagesize of this architecture */ - - pagesize = getpagesize(); - - /* everything's ok */ - - return true; -} - - -/* memory_mmap_anon ************************************************************ - - Maps anonymous memory, even on systems not defining - MAP_ANON(YMOUS). + Convenience function for mprotect. This function also does error + checking. *******************************************************************************/ -void *memory_mmap_anon(void *addr, size_t len, int prot, int flags) +void memory_mprotect(void *addr, size_t len, int prot) { - void *p; - -#if defined(MAP_ANON) || defined(MAP_ANONYMOUS) - p = mmap(addr, len, prot, -# if defined(MAP_ANON) - MAP_ANON | flags, -# else - MAP_ANONYMOUS | flags, -# endif - -1, 0); -#else - int fd; - - fd = open("/dev/zero", O_RDONLY, 0); - - if (fd == -1) - vm_abort("memory_mmap_anon: open failed: %s", strerror(errno)); - - p = mmap(addr, len, prot, flags, fd, 0); -#endif - -#if defined(MAP_FAILED) - if (p == MAP_FAILED) -#else - if (p == (void *) -1) -#endif - vm_abort("memory_mmap_anon: mmap failed: %s", strerror(errno)); - - return p; + if (system_mprotect(addr, len, prot) != 0) + vm_abort("memory_mprotect: system_mprotect failed: %s", + strerror(errno)); } @@ -172,7 +89,7 @@ void *memory_mmap_anon(void *addr, size_t len, int prot, int flags) *******************************************************************************/ -static void *memory_checked_alloc(s4 size) +void *memory_checked_alloc(size_t size) { /* always allocate memory zeroed out */ @@ -185,86 +102,7 @@ static void *memory_checked_alloc(s4 size) } -/* memory_cnew ***************************************************************** - - Allocates memory from the heap via mmap and make the memory read-, - write-, and executeable. - -*******************************************************************************/ - -void *memory_cnew(s4 size) -{ - void *p; - - LOCK_MONITOR_ENTER(lock_code_memory); - - size = MEMORY_ALIGN(size, ALIGNSIZE); - - /* check if enough memory is available */ - - if (size > code_memory_size) { - /* set default code size */ - - code_memory_size = DEFAULT_CODE_MEMORY_SIZE; - - /* do we need more? */ - - if (size > code_memory_size) - code_memory_size = size; - - /* align the size of the memory to be allocated */ - - code_memory_size = MEMORY_ALIGN(code_memory_size, pagesize); - -#if defined(ENABLE_STATISTICS) - if (opt_stat) { - codememusage += code_memory_size; - - if (codememusage > maxcodememusage) - maxcodememusage = codememusage; - } -#endif - - /* allocate the memory */ - - p = memory_mmap_anon(NULL, code_memory_size, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE); - - /* set global code memory pointer */ - - code_memory = p; - } - - /* get a memory chunk of the allocated memory */ - - p = code_memory; - - code_memory = (void *) ((ptrint) code_memory + size); - code_memory_size -= size; - - LOCK_MONITOR_EXIT(lock_code_memory); - - return p; -} - - -/* memory_cfree **************************************************************** - - Frees the code memory pointed to. - - ATTENTION: This function currently does NOTHING! Because we don't - have a memory management for code memory. - -*******************************************************************************/ - -void memory_cfree(void *p, s4 size) -{ - /* do nothing */ -} - - -void *mem_alloc(s4 size) +void *mem_alloc(int32_t size) { void *m; @@ -292,7 +130,7 @@ void *mem_alloc(s4 size) } -void *mem_realloc(void *src, s4 len1, s4 len2) +void *mem_realloc(void *src, int32_t len1, int32_t len2) { void *dst; @@ -328,7 +166,7 @@ void *mem_realloc(void *src, s4 len1, s4 len2) } -void mem_free(void *m, s4 size) +void mem_free(void *m, int32_t size) { if (!m) { if (size == 0) @@ -363,6 +201,10 @@ static void memory_thread(void) { int32_t seconds; + /* Prevent compiler warning. */ + + seconds = 1; + /* If both arguments are specified, use the value of ProfileMemoryUsage. */ @@ -424,370 +266,6 @@ bool memory_start_thread(void) #endif -/* dump_check_canaries ********************************************************* - - Check canaries in dump memory. - - IN: - di...........dumpinfo_t * of the dump area to check - bottomsize...dump size down to which the dump area should be checked - (specify 0 to check the whole dump area) - - ERROR HANDLING: - If any canary has been changed, this function aborts the VM with - an error message. - -*******************************************************************************/ - -#if defined(ENABLE_MEMCHECK) -void dump_check_canaries(dumpinfo_t *di, s4 bottomsize) -{ - dump_allocation_t *da; - u1 *pm; - s4 i, j; - - /* iterate over all dump memory allocations above bottomsize */ - - da = di->allocations; - while (da && da->useddumpsize >= bottomsize) { - /* check canaries */ - - pm = da->mem - MEMORY_CANARY_SIZE; - for (i=0; isize, da->mem); - } - - pm = da->mem + da->size; - for (i=0; isize, da->mem); - } - - da = da->next; - } -} -#endif /* defined(ENABLE_MEMCHECK) */ - - -/* dump_alloc ****************************************************************** - - Allocate memory in the dump area. - - IN: - size.........size of block to allocate, in bytes - may be zero, in which case NULL is returned - - RETURN VALUE: - pointer to allocated memory, or - NULL iff `size` was zero - - ERROR HANDLING: - XXX This function uses `memory_checked_alloc`, which *exits* if no - memory could be allocated. - - THREADS: - dump_alloc is thread safe. Each thread has its own dump memory area. - - dump_alloc is a fast allocator suitable for scratch memory that can be - collectively freed when the current activity (eg. compiling) is done. - - You cannot selectively free dump memory. Before you start allocating it, - you remember the current size returned by `dump_size`. Later, when you no - longer need the memory, call `dump_release` with the remembered size and - all dump memory allocated since the call to `dump_size` will be freed. - -*******************************************************************************/ - -void *dump_alloc(s4 size) -{ -#if defined(DISABLE_DUMP) - - /* use malloc memory for dump memory (for debugging only!) */ - - return mem_alloc(size); - -#else /* !defined(DISABLE_DUMP) */ - - void *m; - dumpinfo_t *di; -#if defined(ENABLE_MEMCHECK) - s4 origsize = size; /* needed for the canary system */ -#endif - - /* If no threads are used, the dumpinfo structure is a static structure */ - /* defined at the top of this file. */ - - di = DUMPINFO; - - if (size == 0) - return NULL; - -#if defined(ENABLE_MEMCHECK) - size += 2*MEMORY_CANARY_SIZE; -#endif - - size = MEMORY_ALIGN(size, ALIGNSIZE); - - if (di->useddumpsize + size > di->allocateddumpsize) { - dumpblock_t *newdumpblock; - s4 newdumpblocksize; - - /* allocate a new dumplist structure */ - - newdumpblock = memory_checked_alloc(sizeof(dumpblock_t)); - - /* If requested size is greater than the default, make the new dump */ - /* block as big as the size requested. Else use the default size. */ - - if (size > DUMPBLOCKSIZE) { - newdumpblocksize = size; - - } else { - newdumpblocksize = DUMPBLOCKSIZE; - } - - /* allocate dumpblock memory */ - - newdumpblock->dumpmem = memory_checked_alloc(newdumpblocksize); - - newdumpblock->prev = di->currentdumpblock; - newdumpblock->size = newdumpblocksize; - di->currentdumpblock = newdumpblock; - - /* Used dump size is previously allocated dump size, because the */ - /* remaining free memory of the previous dump block cannot be used. */ - - di->useddumpsize = di->allocateddumpsize; - - /* increase the allocated dump size by the size of the new dump block */ - - di->allocateddumpsize += newdumpblocksize; - -#if defined(ENABLE_STATISTICS) - /* the amount of globally allocated dump memory (thread save) */ - - if (opt_stat) - globalallocateddumpsize += newdumpblocksize; -#endif - } - - /* current dump block base address + the size of the current dump block - */ - /* the size of the unused memory = new start address */ - - m = di->currentdumpblock->dumpmem + di->currentdumpblock->size - - (di->allocateddumpsize - di->useddumpsize); - -#if defined(ENABLE_MEMCHECK) - { - dump_allocation_t *da = NEW(dump_allocation_t); - s4 i; - u1 *pm; - - /* add the allocation to our linked list of allocations */ - - da->next = di->allocations; - da->mem = (u1*) m + MEMORY_CANARY_SIZE; - da->size = origsize; - da->useddumpsize = di->useddumpsize; - - di->allocations = da; - - /* write the canaries */ - - pm = (u1*)m; - for (i=0; imem + da->size; - for (i=0; isize); - } -#endif /* defined(ENABLE_MEMCHECK) */ - - /* increase used dump size by the allocated memory size */ - - di->useddumpsize += size; - -#if defined(ENABLE_STATISTICS) - if (opt_stat) - if (di->useddumpsize > maxdumpsize) - maxdumpsize = di->useddumpsize; -#endif - - return m; - -#endif /* defined(DISABLE_DUMP) */ -} - - -/* dump_realloc **************************************************************** - - Stupid realloc implementation for dump memory. Avoid, if possible. - -*******************************************************************************/ - -void *dump_realloc(void *src, s4 len1, s4 len2) -{ -#if defined(DISABLE_DUMP) - /* use malloc memory for dump memory (for debugging only!) */ - - return mem_realloc(src, len1, len2); -#else - void *dst = dump_alloc(len2); - - memcpy(dst, src, len1); - -#if defined(ENABLE_MEMCHECK) - /* destroy the source */ - memset(src, MEMORY_CLEAR_BYTE, len1); -#endif - - return dst; -#endif -} - - -/* dump_release **************************************************************** - - Release dump memory above the given size. - - IN: - size........All dump memory above this mark will be freed. Usually - `size` will be the return value of a `dump_size` call - made earlier. - - ERROR HANDLING: - XXX If the given size is invalid, this function *exits* with an - error message. - - See `dump_alloc`. - -*******************************************************************************/ - -void dump_release(s4 size) -{ -#if defined(DISABLE_DUMP) - - /* use malloc memory for dump memory (for debugging only!) */ - - /* do nothing */ - -#else /* !defined(DISABLE_DUMP) */ - - dumpinfo_t *di; - - /* If no threads are used, the dumpinfo structure is a static structure */ - /* defined at the top of this file. */ - - di = DUMPINFO; - - if ((size < 0) || (size > di->useddumpsize)) - vm_abort("Illegal dump release size: %d", size); - -#if defined(ENABLE_MEMCHECK) - { - dump_allocation_t *da, *next; - - /* check canaries */ - - dump_check_canaries(di, size); - - /* iterate over all dump memory allocations about to be released */ - - da = di->allocations; - while (da && da->useddumpsize >= size) { - next = da->next; - - /* invalidate the freed memory */ - - memset(da->mem, MEMORY_CLEAR_BYTE, da->size); - - FREE(da, dump_allocation_t); - - da = next; - } - di->allocations = da; - } -#endif /* defined(ENABLE_MEMCHECK) */ - - /* reset the used dump size to the size specified */ - - di->useddumpsize = size; - - while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) { - dumpblock_t *tmp = di->currentdumpblock; - - di->allocateddumpsize -= tmp->size; - di->currentdumpblock = tmp->prev; - -#if defined(ENABLE_STATISTICS) - /* the amount of globally allocated dump memory (thread save) */ - - if (opt_stat) - globalallocateddumpsize -= tmp->size; -#endif - - /* release the dump memory and the dumpinfo structure */ - - free(tmp->dumpmem); - free(tmp); - } - -#endif /* defined(DISABLE_DUMP) */ -} - - -/* dump_size ******************************************************************* - - Return the current size of the dump memory area. See `dump_alloc`. - -*******************************************************************************/ - -s4 dump_size(void) -{ -#if defined(DISABLE_DUMP) - /* use malloc memory for dump memory (for debugging only!) */ - - return 0; - -#else /* !defined(DISABLE_DUMP) */ - - dumpinfo_t *di; - - /* If no threads are used, the dumpinfo structure is a static structure */ - /* defined at the top of this file. */ - - di = DUMPINFO; - - if (di == NULL) - return 0; - - return di->useddumpsize; - -#endif /* defined(DISABLE_DUMP) */ -} - - /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where