Authors: Reinhard Grafl
- $Id: memory.c 1335 2004-07-21 15:57:10Z twisti $
+ $Id: memory.c 1437 2004-11-05 09:51:07Z twisti $
*/
#include "exceptions.h"
#include "global.h"
#include "native.h"
+#include "options.h"
+#include "statistics.h"
+#include "threads/nativethread.h"
#include "toolbox/logging.h"
#include "toolbox/memory.h"
/********* general types, variables and auxiliary functions *********/
-#define DUMPBLOCKSIZE (2<<21)
-#define ALIGNSIZE 8
-
-typedef struct dumplist {
- struct dumplist *prev;
- char *dumpmem;
- int size;
-} dumplist;
-
-
static int mmapcodesize = 0;
static void *mmapcodeptr = NULL;
-long int memoryusage = 0;
-
-long int dumpsize = 0;
-long int dumpspace = 0;
-dumplist *topdumpblock = NULL;
-
-long int maxmemusage = 0;
-long int maxdumpsize = 0;
-
-
-static void *lit_checked_alloc(int length)
-{
- void *m = malloc(length);
-
- if (!m)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
-
- /* not setting to zero causes cacao to segfault (String.hashCode() is
- completely wrong) */
- memset(m, 0, length);
- return m;
-}
+/*******************************************************************************
+ This structure is used for dump memory allocation if cacao runs without
+ threads.
-static void *checked_alloc(int length)
-{
- void *m = malloc(length);
+*******************************************************************************/
- if (!m)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
-
- return m;
-}
+#if !defined(USE_THREADS)
+static dumpinfo nothreads_dumpinfo;
+#endif
-void *mem_mmap(int length)
+void *mem_mmap(int size)
{
- void *retptr;
+ void *m;
- length = ALIGN(length, ALIGNSIZE);
+ size = ALIGN(size, ALIGNSIZE);
- if (length > mmapcodesize) {
+ if (size > mmapcodesize) {
mmapcodesize = 0x10000;
- if (length > mmapcodesize)
- mmapcodesize = length;
+ if (size > mmapcodesize)
+ mmapcodesize = size;
mmapcodesize = ALIGN(mmapcodesize, getpagesize());
- mmapcodeptr = mmap (NULL,
- (size_t) mmapcodesize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS,
- -1,
- (off_t) 0);
+ mmapcodeptr = mmap(NULL,
+ (size_t) mmapcodesize,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ (off_t) 0);
if (mmapcodeptr == MAP_FAILED)
throw_cacao_exception_exit(string_java_lang_InternalError,
"Out of memory");
}
- retptr = mmapcodeptr;
- mmapcodeptr = (void *) ((char *) mmapcodeptr + length);
- mmapcodesize -= length;
+ m = mmapcodeptr;
+ mmapcodeptr = (void *) ((char *) mmapcodeptr + size);
+ mmapcodesize -= size;
- return retptr;
+ return m;
}
-void *mem_alloc(int length)
+static void *checked_alloc(int size)
{
- if (length == 0)
- return NULL;
+ /* always allocate memory zeroed out */
+ void *m = calloc(size, 1);
- memoryusage += length;
- if (memoryusage > maxmemusage)
- maxmemusage = memoryusage;
-
- return checked_alloc(length);
+ if (!m)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Out of memory");
+
+ return m;
}
-void *lit_mem_alloc(int length)
+void *mem_alloc(int size)
{
- if (length == 0)
+ if (size == 0)
return NULL;
- memoryusage += length;
- if (memoryusage > maxmemusage)
- maxmemusage = memoryusage;
+ if (opt_stat) {
+ memoryusage += size;
+
+ if (memoryusage > maxmemusage)
+ maxmemusage = memoryusage;
+ }
- return lit_checked_alloc(length);
+ return checked_alloc(size);
}
-void mem_free(void *m, int length)
+void *mem_realloc(void *src, int len1, int len2)
{
- if (!m) {
- if (length == 0)
- return;
- panic("returned memoryblock with address NULL, length != 0");
+ void *dst;
+
+ if (!src) {
+ if (len1 != 0)
+ panic("reallocating memoryblock with address NULL, length != 0");
}
- memoryusage -= length;
+ if (opt_stat)
+ memoryusage = (memoryusage - len1) + len2;
- free(m);
+ dst = realloc(src, len2);
+
+ if (!dst)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Out of memory");
+
+ return dst;
}
-void lit_mem_free(void *m, int length)
+void mem_free(void *m, int size)
{
if (!m) {
- if (length == 0)
+ if (size == 0)
return;
panic("returned memoryblock with address NULL, length != 0");
}
- memoryusage -= length;
+ if (opt_stat)
+ memoryusage -= size;
free(m);
}
-void *mem_realloc(void *m1, int len1, int len2)
+void *dump_alloc(int size)
{
- void *m2;
+ void *m;
+ dumpinfo *di;
- if (!m1) {
- if (len1 != 0)
- panic("reallocating memoryblock with address NULL, length != 0");
- }
-
- memoryusage = (memoryusage - len1) + len2;
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
- m2 = realloc(m1, len2);
+ if (size == 0)
+ return NULL;
- if (!m2)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
+ size = ALIGN(size, ALIGNSIZE);
- return m2;
-}
+ if (di->useddumpsize + size > di->allocateddumpsize) {
+ dumpblock *newdumpblock;
+ s4 newdumpblocksize;
+ /* allocate a new dumplist structure */
+ newdumpblock = checked_alloc(sizeof(dumpblock));
-/******* common memory manager parts ******/
+ /* 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;
-long int mem_usage()
-{
- return memoryusage;
-}
+ } else {
+ newdumpblocksize = DUMPBLOCKSIZE;
+ }
+ /* allocate dumpblock memory */
+ //printf("new dumpblock: %d\n", newdumpblocksize);
+ newdumpblock->dumpmem = checked_alloc(newdumpblocksize);
-void *dump_alloc(int length)
-{
-#if 1
- return checked_alloc(length);
-#else
- void *m;
- int blocksize = DUMPBLOCKSIZE;
+ newdumpblock->prev = di->currentdumpblock;
+ newdumpblock->size = newdumpblocksize;
+ di->currentdumpblock = newdumpblock;
- if (length == 0) return NULL;
-
- length = ALIGN(length, ALIGNSIZE);
+ /* Used dump size is previously allocated dump size, because the */
+ /* remaining free memory of the previous dump block cannot be used. */
+ //printf("unused memory: %d\n", allocateddumpsize - useddumpsize);
+ di->useddumpsize = di->allocateddumpsize;
- if (length > DUMPBLOCKSIZE)
- blocksize = length;
- assert(length > 0);
+ /* increase the allocated dump size by the size of the new dump block */
+ di->allocateddumpsize += newdumpblocksize;
- if (dumpsize + length > dumpspace) {
- dumplist *newdumpblock = checked_alloc(sizeof(dumplist));
+ /* the amount of globally allocated dump memory (thread save) */
+ if (opt_stat)
+ globalallocateddumpsize += newdumpblocksize;
+ }
- newdumpblock->prev = topdumpblock;
- newdumpblock->size = blocksize;
- topdumpblock = newdumpblock;
+ /* 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);
- newdumpblock->dumpmem = checked_alloc(blocksize);
+ /* increase used dump size by the allocated memory size */
+ di->useddumpsize += size;
- dumpsize = dumpspace;
- dumpspace += blocksize;
- }
-
- m = topdumpblock->dumpmem + blocksize - (dumpspace - dumpsize);
- dumpsize += length;
-
- if (dumpsize > maxdumpsize) {
- maxdumpsize = dumpsize;
+ if (opt_stat) {
+ if (di->useddumpsize > maxdumpsize) {
+ maxdumpsize = di->useddumpsize;
+ }
}
return m;
-#endif
}
-void *dump_realloc(void *ptr, int len1, int len2)
+void *dump_realloc(void *src, int len1, int len2)
{
- void *p2 = dump_alloc(len2);
+ void *dst = dump_alloc(len2);
- memcpy(p2, ptr, len1);
+ memcpy(dst, src, len1);
- return p2;
+ return dst;
}
-long int dump_size()
+void dump_release(int size)
{
- return dumpsize;
-}
+ dumpinfo *di;
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
-void dump_release(long int size)
-{
- return;
- assert(size >= 0 && size <= dumpsize);
+ if (size < 0 || size > di->useddumpsize)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Illegal dump release size %d", size);
- dumpsize = size;
-
- while (topdumpblock && (dumpspace - topdumpblock->size >= dumpsize)) {
- dumplist *oldtop = topdumpblock;
+ /* reset the used dump size to the size specified */
+ di->useddumpsize = size;
+ while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) {
+ dumpblock *tmp = di->currentdumpblock;
+
+#if 0
+ /* XXX TWISTI: can someone explain this to me? */
#ifdef TRACECALLARGS
/* Keep the first dumpblock if we don't free memory. Otherwise
* a new dumpblock is allocated each time and we run out of
*/
if (!oldtop->prev) break;
#endif
-
- dumpspace -= oldtop->size;
- topdumpblock = oldtop->prev;
-
- free(oldtop->dumpmem);
- free(oldtop);
- }
+#endif
+
+ di->allocateddumpsize -= tmp->size;
+ di->currentdumpblock = tmp->prev;
+
+ /* the amount of globally allocated dump memory (thread save) */
+ if (opt_stat)
+ globalallocateddumpsize -= tmp->size;
+
+ /* release the dump memory and the dumpinfo structure */
+ free(tmp->dumpmem);
+ free(tmp);
+ }
}
-void mem_usagelog (int givewarnings)
+long dump_size()
{
- if ((memoryusage != 0) && givewarnings) {
- dolog("Allocated memory not returned: %d", (s4) memoryusage);
- }
+ dumpinfo *di;
- if ((dumpsize != 0) && givewarnings) {
- dolog("Dump memory not returned: %d", (s4) dumpsize);
- }
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
- dolog("Random/Dump - memory usage: %dK/%dK",
- (s4) ((maxmemusage + 1023) / 1024),
- (s4) ((maxdumpsize + 1023) / 1024));
+ return di->useddumpsize;
}
Authors: Reinhard Grafl
- $Id: memory.h 739 2003-12-13 18:52:21Z stefan $
+ $Id: memory.h 1437 2004-11-05 09:51:07Z twisti $
*/
*/
+
+#define DUMPBLOCKSIZE 2 << 13 /* 2 * 8192 bytes */
+#define ALIGNSIZE 8
+
+
+/* dumpblock *******************************************************************
+
+ TODO
+
+*******************************************************************************/
+
+typedef struct dumpblock dumpblock;
+
+struct dumpblock {
+ dumpblock *prev;
+ void *dumpmem;
+ s4 size;
+};
+
+
+/* dumpinfo ********************************************************************
+
+ TODO
+
+*******************************************************************************/
+
+typedef struct dumpinfo dumpinfo;
+
+struct dumpinfo {
+ dumpblock *currentdumpblock;
+ s4 allocateddumpsize;
+ s4 useddumpsize;
+};
+
+
/* Uncollectable memory which can contain references */
void *heap_alloc_uncollectable(u4 bytelen);
void heap_free(void *);
+
#define GCNEW(type,num) heap_alloc_uncollectable(sizeof(type) * (num))
#define GCFREE(ptr) heap_free(ptr)
#define NEW(type) ((type*) mem_alloc(sizeof(type)))
#define FREE(ptr,type) mem_free(ptr, sizeof(type))
-#define LNEW(type) ((type*) lit_mem_alloc(sizeof(type)))
-#define LFREE(ptr,type) lit_mem_free(ptr, sizeof(type))
-
#define MNEW(type,num) ((type*) mem_alloc(sizeof(type) * (num)))
#define MFREE(ptr,type,num) mem_free(ptr, sizeof(type) * (num))
#define MREALLOC(ptr,type,num1,num2) mem_realloc(ptr, sizeof(type) * (num1), \
#define MCOPY(dest,src,type,num) memcpy(dest,src, sizeof(type)* (num))
-#ifdef USE_CODEMMAP
+#if defined(USE_CODEMMAP)
#define CNEW(type,num) ((type*) mem_mmap( sizeof(type) * (num)))
#define CFREE(ptr,num)
#else
#endif
-void *mem_alloc(int length);
-void *mem_mmap(int length);
-void *lit_mem_alloc(int length);
-void mem_free(void *m, int length);
-void lit_mem_free(void *m, int length);
-void *mem_realloc(void *m, int len1, int len2);
-long int mem_usage();
+/* function prototypes */
+
+void *mem_mmap(int size);
+void *mem_alloc(int size);
+void mem_free(void *m, int size);
+void *mem_realloc(void *src, int len1, int len2);
-void *dump_alloc(int length);
-void *dump_realloc(void *m, int len1, int len2);
-long int dump_size();
-void dump_release(long int size);
+void *dump_alloc(int size);
+void *dump_realloc(void *src, int len1, int len2);
+long dump_size();
+void dump_release(int size);
-void mem_usagelog(int givewarnings);
-
#endif /* _MEMORY_H */
Authors: Reinhard Grafl
- $Id: memory.c 1335 2004-07-21 15:57:10Z twisti $
+ $Id: memory.c 1437 2004-11-05 09:51:07Z twisti $
*/
#include "exceptions.h"
#include "global.h"
#include "native.h"
+#include "options.h"
+#include "statistics.h"
+#include "threads/nativethread.h"
#include "toolbox/logging.h"
#include "toolbox/memory.h"
/********* general types, variables and auxiliary functions *********/
-#define DUMPBLOCKSIZE (2<<21)
-#define ALIGNSIZE 8
-
-typedef struct dumplist {
- struct dumplist *prev;
- char *dumpmem;
- int size;
-} dumplist;
-
-
static int mmapcodesize = 0;
static void *mmapcodeptr = NULL;
-long int memoryusage = 0;
-
-long int dumpsize = 0;
-long int dumpspace = 0;
-dumplist *topdumpblock = NULL;
-
-long int maxmemusage = 0;
-long int maxdumpsize = 0;
-
-
-static void *lit_checked_alloc(int length)
-{
- void *m = malloc(length);
-
- if (!m)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
-
- /* not setting to zero causes cacao to segfault (String.hashCode() is
- completely wrong) */
- memset(m, 0, length);
- return m;
-}
+/*******************************************************************************
+ This structure is used for dump memory allocation if cacao runs without
+ threads.
-static void *checked_alloc(int length)
-{
- void *m = malloc(length);
+*******************************************************************************/
- if (!m)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
-
- return m;
-}
+#if !defined(USE_THREADS)
+static dumpinfo nothreads_dumpinfo;
+#endif
-void *mem_mmap(int length)
+void *mem_mmap(int size)
{
- void *retptr;
+ void *m;
- length = ALIGN(length, ALIGNSIZE);
+ size = ALIGN(size, ALIGNSIZE);
- if (length > mmapcodesize) {
+ if (size > mmapcodesize) {
mmapcodesize = 0x10000;
- if (length > mmapcodesize)
- mmapcodesize = length;
+ if (size > mmapcodesize)
+ mmapcodesize = size;
mmapcodesize = ALIGN(mmapcodesize, getpagesize());
- mmapcodeptr = mmap (NULL,
- (size_t) mmapcodesize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANONYMOUS,
- -1,
- (off_t) 0);
+ mmapcodeptr = mmap(NULL,
+ (size_t) mmapcodesize,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ -1,
+ (off_t) 0);
if (mmapcodeptr == MAP_FAILED)
throw_cacao_exception_exit(string_java_lang_InternalError,
"Out of memory");
}
- retptr = mmapcodeptr;
- mmapcodeptr = (void *) ((char *) mmapcodeptr + length);
- mmapcodesize -= length;
+ m = mmapcodeptr;
+ mmapcodeptr = (void *) ((char *) mmapcodeptr + size);
+ mmapcodesize -= size;
- return retptr;
+ return m;
}
-void *mem_alloc(int length)
+static void *checked_alloc(int size)
{
- if (length == 0)
- return NULL;
+ /* always allocate memory zeroed out */
+ void *m = calloc(size, 1);
- memoryusage += length;
- if (memoryusage > maxmemusage)
- maxmemusage = memoryusage;
-
- return checked_alloc(length);
+ if (!m)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Out of memory");
+
+ return m;
}
-void *lit_mem_alloc(int length)
+void *mem_alloc(int size)
{
- if (length == 0)
+ if (size == 0)
return NULL;
- memoryusage += length;
- if (memoryusage > maxmemusage)
- maxmemusage = memoryusage;
+ if (opt_stat) {
+ memoryusage += size;
+
+ if (memoryusage > maxmemusage)
+ maxmemusage = memoryusage;
+ }
- return lit_checked_alloc(length);
+ return checked_alloc(size);
}
-void mem_free(void *m, int length)
+void *mem_realloc(void *src, int len1, int len2)
{
- if (!m) {
- if (length == 0)
- return;
- panic("returned memoryblock with address NULL, length != 0");
+ void *dst;
+
+ if (!src) {
+ if (len1 != 0)
+ panic("reallocating memoryblock with address NULL, length != 0");
}
- memoryusage -= length;
+ if (opt_stat)
+ memoryusage = (memoryusage - len1) + len2;
- free(m);
+ dst = realloc(src, len2);
+
+ if (!dst)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Out of memory");
+
+ return dst;
}
-void lit_mem_free(void *m, int length)
+void mem_free(void *m, int size)
{
if (!m) {
- if (length == 0)
+ if (size == 0)
return;
panic("returned memoryblock with address NULL, length != 0");
}
- memoryusage -= length;
+ if (opt_stat)
+ memoryusage -= size;
free(m);
}
-void *mem_realloc(void *m1, int len1, int len2)
+void *dump_alloc(int size)
{
- void *m2;
+ void *m;
+ dumpinfo *di;
- if (!m1) {
- if (len1 != 0)
- panic("reallocating memoryblock with address NULL, length != 0");
- }
-
- memoryusage = (memoryusage - len1) + len2;
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
- m2 = realloc(m1, len2);
+ if (size == 0)
+ return NULL;
- if (!m2)
- throw_cacao_exception_exit(string_java_lang_InternalError,
- "Out of memory");
+ size = ALIGN(size, ALIGNSIZE);
- return m2;
-}
+ if (di->useddumpsize + size > di->allocateddumpsize) {
+ dumpblock *newdumpblock;
+ s4 newdumpblocksize;
+ /* allocate a new dumplist structure */
+ newdumpblock = checked_alloc(sizeof(dumpblock));
-/******* common memory manager parts ******/
+ /* 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;
-long int mem_usage()
-{
- return memoryusage;
-}
+ } else {
+ newdumpblocksize = DUMPBLOCKSIZE;
+ }
+ /* allocate dumpblock memory */
+ //printf("new dumpblock: %d\n", newdumpblocksize);
+ newdumpblock->dumpmem = checked_alloc(newdumpblocksize);
-void *dump_alloc(int length)
-{
-#if 1
- return checked_alloc(length);
-#else
- void *m;
- int blocksize = DUMPBLOCKSIZE;
+ newdumpblock->prev = di->currentdumpblock;
+ newdumpblock->size = newdumpblocksize;
+ di->currentdumpblock = newdumpblock;
- if (length == 0) return NULL;
-
- length = ALIGN(length, ALIGNSIZE);
+ /* Used dump size is previously allocated dump size, because the */
+ /* remaining free memory of the previous dump block cannot be used. */
+ //printf("unused memory: %d\n", allocateddumpsize - useddumpsize);
+ di->useddumpsize = di->allocateddumpsize;
- if (length > DUMPBLOCKSIZE)
- blocksize = length;
- assert(length > 0);
+ /* increase the allocated dump size by the size of the new dump block */
+ di->allocateddumpsize += newdumpblocksize;
- if (dumpsize + length > dumpspace) {
- dumplist *newdumpblock = checked_alloc(sizeof(dumplist));
+ /* the amount of globally allocated dump memory (thread save) */
+ if (opt_stat)
+ globalallocateddumpsize += newdumpblocksize;
+ }
- newdumpblock->prev = topdumpblock;
- newdumpblock->size = blocksize;
- topdumpblock = newdumpblock;
+ /* 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);
- newdumpblock->dumpmem = checked_alloc(blocksize);
+ /* increase used dump size by the allocated memory size */
+ di->useddumpsize += size;
- dumpsize = dumpspace;
- dumpspace += blocksize;
- }
-
- m = topdumpblock->dumpmem + blocksize - (dumpspace - dumpsize);
- dumpsize += length;
-
- if (dumpsize > maxdumpsize) {
- maxdumpsize = dumpsize;
+ if (opt_stat) {
+ if (di->useddumpsize > maxdumpsize) {
+ maxdumpsize = di->useddumpsize;
+ }
}
return m;
-#endif
}
-void *dump_realloc(void *ptr, int len1, int len2)
+void *dump_realloc(void *src, int len1, int len2)
{
- void *p2 = dump_alloc(len2);
+ void *dst = dump_alloc(len2);
- memcpy(p2, ptr, len1);
+ memcpy(dst, src, len1);
- return p2;
+ return dst;
}
-long int dump_size()
+void dump_release(int size)
{
- return dumpsize;
-}
+ dumpinfo *di;
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
-void dump_release(long int size)
-{
- return;
- assert(size >= 0 && size <= dumpsize);
+ if (size < 0 || size > di->useddumpsize)
+ throw_cacao_exception_exit(string_java_lang_InternalError,
+ "Illegal dump release size %d", size);
- dumpsize = size;
-
- while (topdumpblock && (dumpspace - topdumpblock->size >= dumpsize)) {
- dumplist *oldtop = topdumpblock;
+ /* reset the used dump size to the size specified */
+ di->useddumpsize = size;
+ while (di->currentdumpblock && di->allocateddumpsize - di->currentdumpblock->size >= di->useddumpsize) {
+ dumpblock *tmp = di->currentdumpblock;
+
+#if 0
+ /* XXX TWISTI: can someone explain this to me? */
#ifdef TRACECALLARGS
/* Keep the first dumpblock if we don't free memory. Otherwise
* a new dumpblock is allocated each time and we run out of
*/
if (!oldtop->prev) break;
#endif
-
- dumpspace -= oldtop->size;
- topdumpblock = oldtop->prev;
-
- free(oldtop->dumpmem);
- free(oldtop);
- }
+#endif
+
+ di->allocateddumpsize -= tmp->size;
+ di->currentdumpblock = tmp->prev;
+
+ /* the amount of globally allocated dump memory (thread save) */
+ if (opt_stat)
+ globalallocateddumpsize -= tmp->size;
+
+ /* release the dump memory and the dumpinfo structure */
+ free(tmp->dumpmem);
+ free(tmp);
+ }
}
-void mem_usagelog (int givewarnings)
+long dump_size()
{
- if ((memoryusage != 0) && givewarnings) {
- dolog("Allocated memory not returned: %d", (s4) memoryusage);
- }
+ dumpinfo *di;
- if ((dumpsize != 0) && givewarnings) {
- dolog("Dump memory not returned: %d", (s4) dumpsize);
- }
+ /* If no threads are used, the dumpinfo structure is a static structure */
+ /* defined at the top of this file. */
+#if defined(USE_THREADS)
+ di = &((threadobject *) THREADOBJECT)->dumpinfo;
+#else
+ di = ¬hreads_dumpinfo;
+#endif
- dolog("Random/Dump - memory usage: %dK/%dK",
- (s4) ((maxmemusage + 1023) / 1024),
- (s4) ((maxdumpsize + 1023) / 1024));
+ return di->useddumpsize;
}
Authors: Reinhard Grafl
- $Id: memory.h 739 2003-12-13 18:52:21Z stefan $
+ $Id: memory.h 1437 2004-11-05 09:51:07Z twisti $
*/
*/
+
+#define DUMPBLOCKSIZE 2 << 13 /* 2 * 8192 bytes */
+#define ALIGNSIZE 8
+
+
+/* dumpblock *******************************************************************
+
+ TODO
+
+*******************************************************************************/
+
+typedef struct dumpblock dumpblock;
+
+struct dumpblock {
+ dumpblock *prev;
+ void *dumpmem;
+ s4 size;
+};
+
+
+/* dumpinfo ********************************************************************
+
+ TODO
+
+*******************************************************************************/
+
+typedef struct dumpinfo dumpinfo;
+
+struct dumpinfo {
+ dumpblock *currentdumpblock;
+ s4 allocateddumpsize;
+ s4 useddumpsize;
+};
+
+
/* Uncollectable memory which can contain references */
void *heap_alloc_uncollectable(u4 bytelen);
void heap_free(void *);
+
#define GCNEW(type,num) heap_alloc_uncollectable(sizeof(type) * (num))
#define GCFREE(ptr) heap_free(ptr)
#define NEW(type) ((type*) mem_alloc(sizeof(type)))
#define FREE(ptr,type) mem_free(ptr, sizeof(type))
-#define LNEW(type) ((type*) lit_mem_alloc(sizeof(type)))
-#define LFREE(ptr,type) lit_mem_free(ptr, sizeof(type))
-
#define MNEW(type,num) ((type*) mem_alloc(sizeof(type) * (num)))
#define MFREE(ptr,type,num) mem_free(ptr, sizeof(type) * (num))
#define MREALLOC(ptr,type,num1,num2) mem_realloc(ptr, sizeof(type) * (num1), \
#define MCOPY(dest,src,type,num) memcpy(dest,src, sizeof(type)* (num))
-#ifdef USE_CODEMMAP
+#if defined(USE_CODEMMAP)
#define CNEW(type,num) ((type*) mem_mmap( sizeof(type) * (num)))
#define CFREE(ptr,num)
#else
#endif
-void *mem_alloc(int length);
-void *mem_mmap(int length);
-void *lit_mem_alloc(int length);
-void mem_free(void *m, int length);
-void lit_mem_free(void *m, int length);
-void *mem_realloc(void *m, int len1, int len2);
-long int mem_usage();
+/* function prototypes */
+
+void *mem_mmap(int size);
+void *mem_alloc(int size);
+void mem_free(void *m, int size);
+void *mem_realloc(void *src, int len1, int len2);
-void *dump_alloc(int length);
-void *dump_realloc(void *m, int len1, int len2);
-long int dump_size();
-void dump_release(long int size);
+void *dump_alloc(int size);
+void *dump_realloc(void *src, int len1, int len2);
+long dump_size();
+void dump_release(int size);
-void mem_usagelog(int givewarnings);
-
#endif /* _MEMORY_H */