* fixed GCC 4.4.0 mingw compilation:
[fw/sdcc] / support / Util / NewAlloc.c
index 22aa198b5c8f3cc779f0fc1fbd9da7ab4c98a9e5..fb8a180aa75fae876c356533e4bcfa6c554424ba 100644 (file)
@@ -28,16 +28,82 @@ functions.
 */
 
 #include <stdio.h>
-#if defined(__APPLE__) && defined(__MACH__)
-#include <sys/malloc.h>
-#else
-#include <malloc.h>
-#endif
 #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
@@ -51,7 +117,7 @@ void *Clear_realloc(void *OldPtr,size_t OldSize,size_t NewSize)
 {
 void *NewPtr ;
 
-NewPtr = realloc(OldPtr,NewSize) ;
+NewPtr = REALLOC(OldPtr,NewSize) ;
 
 if (!NewPtr)
   {
@@ -78,7 +144,7 @@ void *Safe_realloc(void *OldPtr,size_t NewSize)
 {
 void *NewPtr ;
 
-NewPtr = realloc(OldPtr,NewSize) ;
+NewPtr = REALLOC(OldPtr,NewSize) ;
 
 if (!NewPtr)
   {
@@ -102,8 +168,11 @@ void *Safe_calloc(size_t Elements,size_t Size)
 {
 void *NewPtr ;
 
-NewPtr = calloc(Elements,Size) ;
-
+NewPtr = MALLOC(Elements*Size) ;
+#if TRACEMALLOC
+ _log(Elements*Size);
+#endif
 if (!NewPtr)
   {
   printf("ERROR - No more memory\n") ;
@@ -111,6 +180,8 @@ if (!NewPtr)
   exit (1);
   }
 
+ memset(NewPtr, 0, Elements*Size);
+
 return NewPtr ;
 }
 /*
@@ -126,7 +197,11 @@ void *Safe_malloc(size_t Size)
 {
 void *NewPtr ;
 
-NewPtr = malloc(Size) ;
+NewPtr = MALLOC(Size) ;
+
+#if TRACEMALLOC
+ _log(Size);
+#endif
 
 if (!NewPtr)
   {
@@ -137,3 +212,57 @@ 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;
+}