#include "mempool.h"
+#if USE_MALLOC_FOR_MEMPOOLS
+#define MALLOC_ALLOCATION
+#endif
+
/*
* MonoMemPool is for fast allocation of memory. We free
* all memory when the pool is destroyed.
#define G_UNLIKELY(a) (a)
#endif
+#ifdef MALLOC_ALLOCATION
+typedef struct _Chunk {
+ struct _Chunk *next;
+ guint32 size;
+} Chunk;
+
+struct _MonoMemPool {
+ Chunk *chunks;
+ guint32 allocated;
+};
+#else
struct _MonoMemPool {
MonoMemPool *next;
gint rest;
guint32 allocated;
} d;
};
+#endif
/**
* mono_mempool_new:
MonoMemPool *
mono_mempool_new_size (int initial_size)
{
+#ifdef MALLOC_ALLOCATION
+ return g_new0 (MonoMemPool, 1);
+#else
MonoMemPool *pool;
if (initial_size < MONO_MEMPOOL_MINSIZE)
initial_size = MONO_MEMPOOL_MINSIZE;
pool->end = pool->pos + initial_size - sizeof (MonoMemPool);
pool->d.allocated = pool->size = initial_size;
return pool;
+#endif
}
/**
void
mono_mempool_destroy (MonoMemPool *pool)
{
+#ifdef MALLOC_ALLOCATION
+ mono_mempool_empty (pool);
+
+ g_free (pool);
+#else
MonoMemPool *p, *n;
p = pool;
g_free (p);
p = n;
}
+#endif
}
/**
void
mono_mempool_invalidate (MonoMemPool *pool)
{
+#ifdef MALLOC_ALLOCATION
+ g_assert_not_reached ();
+#else
MonoMemPool *p, *n;
p = pool;
memset (p, 42, p->size);
p = n;
}
+#endif
}
void
mono_mempool_empty (MonoMemPool *pool)
{
+#ifdef MALLOC_ALLOCATION
+ Chunk *p, *n;
+
+ p = pool->chunks;
+ pool->chunks = NULL;
+ while (p) {
+ n = p->next;
+ g_free (p);
+ p = n;
+ }
+
+ pool->allocated = 0;
+#else
pool->pos = (guint8*)pool + sizeof (MonoMemPool);
pool->end = pool->pos + pool->size - sizeof (MonoMemPool);
+#endif
}
/**
void
mono_mempool_stats (MonoMemPool *pool)
{
+#ifdef MALLOC_ALLOCATION
+ g_assert_not_reached ();
+#else
MonoMemPool *p;
int count = 0;
guint32 still_free = 0;
g_print ("Num chunks: %d\n", count);
g_print ("Free memory: %d\n", still_free);
}
+#endif
}
+#ifndef MALLOC_ALLOCATION
#ifdef TRACE_ALLOCATIONS
#include <execinfo.h>
#include "metadata/appdomain.h"
g_assert (size <= MONO_MEMPOOL_PAGESIZE);
return target;
}
+#endif
/**
* mono_mempool_alloc:
size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
+#ifdef MALLOC_ALLOCATION
+ {
+ Chunk *c = g_malloc (sizeof (Chunk) + size);
+
+ c->next = pool->chunks;
+ pool->chunks = c;
+ c->size = size;
+
+ pool->allocated += size;
+
+ rval = ((guint8*)c) + sizeof (Chunk);
+ }
+#else
rval = pool->pos;
pool->pos = (guint8*)rval + size;
}
return rval;
+#endif
}
/**
mono_mempool_alloc0 (MonoMemPool *pool, guint size)
{
gpointer rval;
-
+
+#ifdef MALLOC_ALLOCATION
+ rval = mono_mempool_alloc (pool, size);
+#else
size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
rval = pool->pos;
if (G_UNLIKELY (pool->pos >= pool->end)) {
rval = mono_mempool_alloc (pool, size);
}
+#endif
memset (rval, 0, size);
return rval;
mono_mempool_contains_addr (MonoMemPool *pool,
gpointer addr)
{
+#ifdef MALLOC_ALLOCATION
+ Chunk *c;
+
+ c = pool->chunks;
+ while (c) {
+ guint8 *p = ((guint8*)c) + sizeof (Chunk);
+
+ if (addr >= (gpointer)p && addr < (gpointer)(p + c->size))
+ return TRUE;
+
+ c = c->next;
+ }
+#else
MonoMemPool *p;
p = pool;
return TRUE;
p = p->next;
}
+#endif
return FALSE;
}
guint32
mono_mempool_get_allocated (MonoMemPool *pool)
{
+#ifdef MALLOC_ALLOCATION
+ return pool->allocated;
+#else
return pool->d.allocated;
+#endif
}