2 * mempool.c: efficient memory allocation
4 * MonoMemPool is for fast allocation of memory. We free
5 * all memory when the pool is destroyed.
8 * Dietmar Maurer (dietmar@ximian.com)
10 * (C) 2001 Ximian, Inc.
20 * MonoMemPool is for fast allocation of memory. We free
21 * all memory when the pool is destroyed.
26 #define MONO_MEMPOOL_PAGESIZE 8192
29 #define G_LIKELY(a) (a)
30 #define G_UNLIKELY(a) (a)
39 double pad; /* to assure proper alignment */
47 * Returns: a new memory pool.
52 MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
55 pool->pos = (guint8*)pool + sizeof (MonoMemPool);
56 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
57 pool->d.allocated = pool->size = MONO_MEMPOOL_PAGESIZE;
62 * mono_mempool_destroy:
63 * @pool: the memory pool to destroy
65 * Free all memory associated with this pool.
68 mono_mempool_destroy (MonoMemPool *pool)
81 * mono_mempool_invalidate:
82 * @pool: the memory pool to invalidate
84 * Fill the memory associated with this pool to 0x2a (42). Useful for debugging.
87 mono_mempool_invalidate (MonoMemPool *pool)
94 memset (p, 42, p->size);
100 mono_mempool_empty (MonoMemPool *pool)
102 pool->pos = (guint8*)pool + sizeof (MonoMemPool);
103 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
107 * mono_mempool_stats:
108 * @pool: the momory pool we need stats for
110 * Print a few stats about the mempool
113 mono_mempool_stats (MonoMemPool *pool)
117 guint32 still_free = 0;
121 still_free += p->end - p->pos;
126 g_print ("Mempool %p stats:\n", pool);
127 g_print ("Total mem allocated: %d\n", pool->d.allocated);
128 g_print ("Num chunks: %d\n", count);
129 g_print ("Free memory: %d\n", still_free);
133 #ifdef TRACE_ALLOCATIONS
134 #include <execinfo.h>
135 #include "metadata/appdomain.h"
136 #include "metadata/metadata-internals.h"
139 mono_backtrace (int limit)
144 backtrace (array, limit);
145 names = backtrace_symbols (array, limit);
146 for (i = 1; i < limit; ++i) {
147 g_print ("\t%s\n", names [i]);
155 * mono_mempool_alloc:
156 * @pool: the momory pool to destroy
157 * @size: size of the momory block
159 * Allocates a new block of memory in @pool.
161 * Returns: the address of a newly allocated memory block.
164 mono_mempool_alloc (MonoMemPool *pool, guint size)
168 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
171 pool->pos = (guint8*)rval + size;
173 #ifdef TRACE_ALLOCATIONS
174 if (pool == mono_get_corlib ()->mempool) {
175 g_print ("Allocating %d bytes\n", size);
179 if (G_UNLIKELY (pool->pos >= pool->end)) {
182 MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
183 np->next = pool->next;
185 np->pos = (guint8*)np + sizeof (MonoMemPool);
186 np->size = sizeof (MonoMemPool) + size;
187 np->end = np->pos + np->size - sizeof (MonoMemPool);
188 pool->d.allocated += sizeof (MonoMemPool) + size;
189 return (guint8*)np + sizeof (MonoMemPool);
191 MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
192 np->next = pool->next;
194 pool->pos = (guint8*)np + sizeof (MonoMemPool);
195 np->pos = (guint8*)np + sizeof (MonoMemPool);
196 np->size = MONO_MEMPOOL_PAGESIZE;
198 pool->end = pool->pos + MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
199 pool->d.allocated += MONO_MEMPOOL_PAGESIZE;
210 * mono_mempool_alloc0:
212 * same as mono_mempool_alloc, but fills memory with zero.
215 mono_mempool_alloc0 (MonoMemPool *pool, guint size)
219 size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
222 pool->pos = (guint8*)rval + size;
224 if (G_UNLIKELY (pool->pos >= pool->end)) {
225 rval = mono_mempool_alloc (pool, size);
228 memset (rval, 0, size);
233 * mono_mempool_contains_addr:
235 * Determines whenever ADDR is inside the memory used by the mempool.
238 mono_mempool_contains_addr (MonoMemPool *pool,
245 if (addr > (gpointer)p && addr <= (gpointer)((guint8*)p + p->size))
254 * mono_mempool_strdup:
256 * Same as strdup, but allocates memory from the mempool.
257 * Returns: a pointer to the newly allocated string data inside the mempool.
260 mono_mempool_strdup (MonoMemPool *pool,
270 res = mono_mempool_alloc (pool, l + 1);
271 memcpy (res, s, l + 1);
277 * mono_mempool_get_allocated:
279 * Return the amount of memory allocated for this mempool.
282 mono_mempool_get_allocated (MonoMemPool *pool)
284 return pool->d.allocated;