This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mono / metadata / mempool.c
index 525cdd3a8525916e5b1bfc988ed4ccbfee6424ea..53c76492732db78b57bd4be3d3e38192c3852cac 100644 (file)
 #include <glib.h>
 #include <string.h>
 
-#include "jit.h"
+#include "mempool.h"
 
 /*
  * MonoMemPool is for fast allocation of memory. We free
  * all memory when the pool is destroyed.
  */
 
-#if SIZEOF_VOID_P > SIZEOF_LONG
-#define MEM_ALIGN     SIZEOF_VOID_P
-#else
-#define MEM_ALIGN     SIZEOF_LONG
-#endif
+#define MEM_ALIGN 8
 
 #define MONO_MEMPOOL_PAGESIZE 8192
 
@@ -33,6 +29,11 @@ struct _MonoMemPool {
        MonoMemPool *next;
        gint rest;
        gpointer pos;
+       guint32 size;
+       union {
+               double pad; /* to assure proper alignment */
+               guint32 allocated;
+       } d;
 };
 
 /**
@@ -43,17 +44,18 @@ struct _MonoMemPool {
 MonoMemPool *
 mono_mempool_new ()
 {
-
        MonoMemPool *pool = g_malloc (MONO_MEMPOOL_PAGESIZE);
+
        pool->next = NULL;
-       pool->pos = (gpointer)pool + sizeof (MonoMemPool);
+       pool->pos = (char *)pool + sizeof (MonoMemPool);
        pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+       pool->d.allocated = pool->size = MONO_MEMPOOL_PAGESIZE;
        return pool;
 }
 
 /**
  * mono_mempool_destroy:
- * @pool: the momory pool to destroy
+ * @pool: the memory pool to destroy
  *
  * Free all memory associated with this pool.
  */
@@ -70,6 +72,60 @@ mono_mempool_destroy (MonoMemPool *pool)
        }
 }
 
+/**
+ * mono_mempool_invalidate:
+ * @pool: the memory pool to invalidate
+ *
+ * Fill the memory associated with this pool to 0x2a (42). Useful for debugging.
+ */
+void
+mono_mempool_invalidate (MonoMemPool *pool)
+{
+       MonoMemPool *p, *n;
+
+       p = pool;
+       while (p) {
+               n = p->next;
+               memset (p, 42, p->size);
+               p = n;
+       }
+}
+
+void
+mono_mempool_empty (MonoMemPool *pool)
+{
+       pool->pos = (char *)pool + sizeof (MonoMemPool);
+       pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+}
+
+/**
+ * mono_mempool_stats:
+ * @pool: the momory pool we need stats for
+ *
+ * Print a few stats about the mempool
+ */
+void
+mono_mempool_stats (MonoMemPool *pool)
+{
+       MonoMemPool *p, *n;
+       int count = 0;
+       guint32 still_free = 0;
+
+       p = pool;
+       while (p) {
+               still_free += p->rest;
+               n = p->next;
+               p = n;
+               count++;
+       }
+       if (pool) {
+               g_print ("Mempool %p stats:\n", pool);
+               g_print ("Total mem allocated: %d\n", pool->d.allocated);
+               g_print ("Num chunks: %d\n", count);
+               g_print ("Free memory: %d\n", still_free);
+       }
+}
+
 /**
  * mono_mempool_alloc:
  * @pool: the momory pool to destroy
@@ -87,26 +143,30 @@ mono_mempool_alloc (MonoMemPool *pool, guint size)
        
        g_assert (pool != NULL);
 
-       if (size >= 4096) {
-               MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
-               np->next = pool->next;
-               pool->next = np;
-               return (gpointer)np + sizeof (MonoMemPool);
-       }
-
        size = (size + MEM_ALIGN - 1) & ~(MEM_ALIGN - 1);
 
        if (pool->rest < size) {
-               MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
-               np->next = pool->next;
-               pool->next = np;
-               pool->pos = (gpointer)np + sizeof (MonoMemPool);
-               pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+               if (size >= 4096) {
+                       MonoMemPool *np = g_malloc (sizeof (MonoMemPool) + size);
+                       np->next = pool->next;
+                       pool->next = np;
+                       np->size = sizeof (MonoMemPool) + size;
+                       pool->d.allocated += sizeof (MonoMemPool) + size;
+                       return (char *)np + sizeof (MonoMemPool);
+               } else {
+                       MonoMemPool *np = g_malloc (MONO_MEMPOOL_PAGESIZE);
+                       np->next = pool->next;
+                       pool->next = np;
+                       pool->pos = (char *)np + sizeof (MonoMemPool);
+                       np->size = MONO_MEMPOOL_PAGESIZE;
+                       pool->rest = MONO_MEMPOOL_PAGESIZE - sizeof (MonoMemPool);
+                       pool->d.allocated += MONO_MEMPOOL_PAGESIZE;
+               }
        }
 
        rval = pool->pos;
        pool->rest -= size;
-       pool->pos += size;
+       pool->pos = (char *)pool->pos + size;
 
        return rval;
 }