*/
#include <stdio.h>
-#include <malloc.h>
#include <stdlib.h>
+#include <string.h>
#include <memory.h>
-
+#include <assert.h>
#include "newalloc.h"
+
+#if OPT_ENABLE_LIBGC
+#include <gc/gc.h>
+
+#define MALLOC GC_malloc
+#define REALLOC GC_realloc
+/* PENDING: This is a mild hack. If we try to GC_free something
+ allocated with malloc() then the program will segfault. Might as
+ well drop it and let the garbase collector take care of things.
+*/
+#define FREE(_a)
+
+#else
+
+#define MALLOC malloc
+#define REALLOC realloc
+#define FREE free
+
+#endif
+
+#define TRACEMALLOC 0
+
+#if TRACEMALLOC
+enum
+ {
+ TRACESIZE = 4096
+ };
+
+static int _allocs[TRACESIZE];
+static int _above;
+
+static void
+_dumpTrace(int code, void *parg)
+{
+ int i;
+ for (i = 0; i < TRACESIZE; i++)
+ {
+ if (_allocs[i])
+ {
+ printf("%u %u\n", _allocs[i], i);
+ }
+ }
+ printf("%u above\n", _above);
+}
+
+static void
+_log(int size)
+{
+ static int registered;
+
+ if (registered == 0)
+ {
+ on_exit(_dumpTrace, NULL);
+ registered = 1;
+ }
+ if (size == 12)
+ {
+ _above++;
+ }
+
+ if (size >= TRACESIZE)
+ {
+ _above++;
+ }
+ else
+ {
+ _allocs[size]++;
+ }
+}
+#endif
+
/*
-------------------------------------------------------------------------------
Clear_realloc - Reallocate a memory block and clear any memory added with
{
void *NewPtr ;
-NewPtr = realloc(OldPtr,NewSize) ;
+NewPtr = REALLOC(OldPtr,NewSize) ;
if (!NewPtr)
{
{
void *NewPtr ;
-NewPtr = realloc(OldPtr,NewSize) ;
+NewPtr = REALLOC(OldPtr,NewSize) ;
if (!NewPtr)
{
{
void *NewPtr ;
-NewPtr = calloc(Elements,Size) ;
-
+NewPtr = MALLOC(Elements*Size) ;
+#if TRACEMALLOC
+ _log(Elements*Size);
+#endif
+
if (!NewPtr)
{
printf("ERROR - No more memory\n") ;
exit (1);
}
+ memset(NewPtr, 0, Elements*Size);
+
return NewPtr ;
}
/*
{
void *NewPtr ;
-NewPtr = malloc(Size) ;
+NewPtr = MALLOC(Size) ;
+
+#if TRACEMALLOC
+ _log(Size);
+#endif
if (!NewPtr)
{
return NewPtr ;
}
+
+void *Safe_alloc(size_t Size)
+{
+ return Safe_calloc(1, Size);
+}
+
+void Safe_free(void *p)
+{
+ FREE(p);
+}
+
+char *Safe_strdup(const char *sz)
+{
+ char *pret;
+ assert(sz);
+
+ pret = Safe_alloc(strlen(sz) +1);
+ strcpy(pret, sz);
+
+ return pret;
+}
+
+void *traceAlloc(allocTrace *ptrace, void *p)
+{
+ assert(ptrace);
+ assert(p);
+
+ /* Also handles where max == 0 */
+ if (ptrace->num == ptrace->max)
+ {
+ /* Add an offset to handle max == 0 */
+ ptrace->max = (ptrace->max+2)*2;
+ ptrace->palloced = Safe_realloc(ptrace->palloced, ptrace->max * sizeof(*ptrace->palloced));
+ }
+ ptrace->palloced[ptrace->num++] = p;
+
+ return p;
+}
+
+void freeTrace(allocTrace *ptrace)
+{
+ int i;
+ assert(ptrace);
+
+ for (i = 0; i < ptrace->num; i++)
+ {
+ Safe_free(ptrace->palloced[i]);
+ }
+ ptrace->num = 0;
+
+ Safe_free(ptrace->palloced);
+ ptrace->palloced = NULL;
+ ptrace->max = 0;
+}