* src/SDCCpeeph.c (peepHole): Fixed all leaks. Added trace support for freeing...
[fw/sdcc] / support / Util / NewAlloc.c
1 /*
2 ===============================================================================
3 NEWALLOC - SDCC Memory allocation functions
4
5 These functions are wrappers for the standard malloc, realloc and free
6 functions.
7
8
9      This program is free software; you can redistribute it and/or modify it
10    under the terms of the GNU General Public License as published by the
11    Free Software Foundation; either version 2, or (at your option) any
12    later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23    In other words, you are welcome to use, share and improve this program.
24    You are forbidden to forbid anyone else to use, share and improve
25    what you give them.   Help stamp out software-hoarding!
26
27 ===============================================================================
28 */
29
30 #include <stdio.h>
31 #if defined(__APPLE__) && defined(__MACH__)
32 #include <sys/malloc.h>
33 #else
34 #include <malloc.h>
35 #endif
36 #include <stdlib.h>
37 #include <string.h>
38 #include <memory.h>
39 #include <assert.h>
40 #include "newalloc.h"
41 #include "sdccconf.h"
42
43 #if OPT_ENABLE_LIBGC
44 #include <gc/gc.h>
45
46 #define MALLOC  GC_malloc
47 #define REALLOC GC_realloc
48 #define FREE    GC_free
49
50 #else
51
52 #define MALLOC  malloc
53 #define REALLOC realloc
54 #define FREE    free
55
56 #endif
57
58 #define TRACEMALLOC     0
59
60 #if TRACEMALLOC
61 enum 
62   {
63     TRACESIZE = 4096
64   };
65
66 static int _allocs[TRACESIZE];
67 static int _above;
68
69 static void
70 _dumpTrace(int code, void *parg)
71 {
72   int i;
73   for (i = 0; i < TRACESIZE; i++)
74     {
75       if (_allocs[i])
76         {
77           printf("%u %u\n", _allocs[i], i);
78         }
79     }
80   printf("%u above\n", _above);
81 }
82
83 static void
84 _log(int size)
85 {
86   static int registered;
87
88   if (registered == 0)
89     {
90       on_exit(_dumpTrace, NULL);
91       registered = 1;
92     }
93   if (size == 12)
94     {
95       _above++;
96     }
97
98   if (size >= TRACESIZE)
99     {
100       _above++;
101     }
102   else
103     {
104       _allocs[size]++;
105     }
106 }
107 #endif
108
109 /*
110 -------------------------------------------------------------------------------
111 Clear_realloc - Reallocate a memory block and clear any memory added with
112 out of memory error detection
113
114 -------------------------------------------------------------------------------
115 */
116
117 void *Clear_realloc(void *OldPtr,size_t OldSize,size_t NewSize)
118
119 {
120 void *NewPtr ;
121
122 NewPtr = REALLOC(OldPtr,NewSize) ;
123
124 if (!NewPtr)
125   {
126   printf("ERROR - No more memory\n") ;
127 /*  werror(E_OUT_OF_MEM,__FILE__,NewSize);*/
128   exit (1);
129   }
130
131 if (NewPtr)
132   if (NewSize > OldSize)
133     memset((char *) NewPtr + OldSize,0x00,NewSize - OldSize) ;
134
135 return NewPtr ;
136 }
137 /*
138 -------------------------------------------------------------------------------
139 Safe_realloc - Reallocate a memory block with out of memory error detection
140
141 -------------------------------------------------------------------------------
142 */
143
144 void *Safe_realloc(void *OldPtr,size_t NewSize)
145
146 {
147 void *NewPtr ;
148
149 NewPtr = REALLOC(OldPtr,NewSize) ;
150
151 if (!NewPtr)
152   {
153   printf("ERROR - No more memory\n") ;
154 /*  werror(E_OUT_OF_MEM,__FILE__,NewSize);*/
155   exit (1);
156   }
157
158 return NewPtr ;
159 }
160 /*
161 -------------------------------------------------------------------------------
162 Safe_calloc - Allocate a block of memory from the application heap, clearing
163 all data to zero and checking for out of memory errors.
164
165 -------------------------------------------------------------------------------
166 */
167
168 void *Safe_calloc(size_t Elements,size_t Size)
169
170 {
171 void *NewPtr ;
172
173 NewPtr = MALLOC(Elements*Size) ;
174 #if TRACEMALLOC
175  _log(Elements*Size);
176 #endif
177  
178 if (!NewPtr)
179   {
180   printf("ERROR - No more memory\n") ;
181 /*  werror(E_OUT_OF_MEM,__FILE__,Size);*/
182   exit (1);
183   }
184
185  memset(NewPtr, 0, Elements*Size);
186
187 return NewPtr ;
188 }
189 /*
190 -------------------------------------------------------------------------------
191 Safe_malloc - Allocate a block of memory from the application heap
192 and checking for out of memory errors.
193
194 -------------------------------------------------------------------------------
195 */
196
197 void *Safe_malloc(size_t Size)
198
199 {
200 void *NewPtr ;
201
202 NewPtr = MALLOC(Size) ;
203
204 #if TRACEMALLOC
205  _log(Size);
206 #endif
207
208 if (!NewPtr)
209   {
210   printf("ERROR - No more memory\n") ;
211 /*  werror(E_OUT_OF_MEM,__FILE__,Size);*/
212   exit (1);
213   }
214
215 return NewPtr ;
216 }
217
218 void *Safe_alloc(size_t Size)
219 {
220   return Safe_calloc(1, Size);
221 }
222
223 void Safe_free(void *p)
224 {
225   FREE(p);
226 }
227
228 char *Safe_strdup(const char *sz)
229 {
230   char *pret;
231   assert(sz);
232
233   pret = Safe_alloc(strlen(sz) +1);
234   strcpy(pret, sz);
235
236   return pret;
237 }
238
239 void *traceAlloc(allocTrace *ptrace, void *p)
240 {
241   assert(ptrace);
242   assert(p);
243
244   /* Also handles where max == 0 */
245   if (ptrace->num == ptrace->max)
246     {
247       /* Add an offset to handle max == 0 */
248       ptrace->max = (ptrace->max+2)*2;
249       ptrace->palloced = Safe_realloc(ptrace->palloced, ptrace->max * sizeof(*ptrace->palloced));
250     }
251   ptrace->palloced[ptrace->num++] = p;
252
253   return p;
254 }
255
256 void freeTrace(allocTrace *ptrace)
257 {
258   int i;
259   assert(ptrace);
260
261   for (i = 0; i < ptrace->num; i++)
262     {
263       Safe_free(ptrace->palloced[i]);
264     }
265   ptrace->num = 0;
266
267   Safe_free(ptrace->palloced);
268   ptrace->palloced = NULL;
269   ptrace->max = 0;
270 }
271