* support/Util/NewAlloc.c (freeTrace): Changed free for the gc case to not free...
[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 /* PENDING: This is a mild hack.  If we try to GC_free something
49    allocated with malloc() then the program will segfault.  Might as
50    well drop it and let the garbase collector take care of things.
51 */
52 #define FREE(_a)        
53
54 #else
55
56 #define MALLOC  malloc
57 #define REALLOC realloc
58 #define FREE    free
59
60 #endif
61
62 #define TRACEMALLOC     0
63
64 #if TRACEMALLOC
65 enum 
66   {
67     TRACESIZE = 4096
68   };
69
70 static int _allocs[TRACESIZE];
71 static int _above;
72
73 static void
74 _dumpTrace(int code, void *parg)
75 {
76   int i;
77   for (i = 0; i < TRACESIZE; i++)
78     {
79       if (_allocs[i])
80         {
81           printf("%u %u\n", _allocs[i], i);
82         }
83     }
84   printf("%u above\n", _above);
85 }
86
87 static void
88 _log(int size)
89 {
90   static int registered;
91
92   if (registered == 0)
93     {
94       on_exit(_dumpTrace, NULL);
95       registered = 1;
96     }
97   if (size == 12)
98     {
99       _above++;
100     }
101
102   if (size >= TRACESIZE)
103     {
104       _above++;
105     }
106   else
107     {
108       _allocs[size]++;
109     }
110 }
111 #endif
112
113 /*
114 -------------------------------------------------------------------------------
115 Clear_realloc - Reallocate a memory block and clear any memory added with
116 out of memory error detection
117
118 -------------------------------------------------------------------------------
119 */
120
121 void *Clear_realloc(void *OldPtr,size_t OldSize,size_t NewSize)
122
123 {
124 void *NewPtr ;
125
126 NewPtr = REALLOC(OldPtr,NewSize) ;
127
128 if (!NewPtr)
129   {
130   printf("ERROR - No more memory\n") ;
131 /*  werror(E_OUT_OF_MEM,__FILE__,NewSize);*/
132   exit (1);
133   }
134
135 if (NewPtr)
136   if (NewSize > OldSize)
137     memset((char *) NewPtr + OldSize,0x00,NewSize - OldSize) ;
138
139 return NewPtr ;
140 }
141 /*
142 -------------------------------------------------------------------------------
143 Safe_realloc - Reallocate a memory block with out of memory error detection
144
145 -------------------------------------------------------------------------------
146 */
147
148 void *Safe_realloc(void *OldPtr,size_t NewSize)
149
150 {
151 void *NewPtr ;
152
153 NewPtr = REALLOC(OldPtr,NewSize) ;
154
155 if (!NewPtr)
156   {
157   printf("ERROR - No more memory\n") ;
158 /*  werror(E_OUT_OF_MEM,__FILE__,NewSize);*/
159   exit (1);
160   }
161
162 return NewPtr ;
163 }
164 /*
165 -------------------------------------------------------------------------------
166 Safe_calloc - Allocate a block of memory from the application heap, clearing
167 all data to zero and checking for out of memory errors.
168
169 -------------------------------------------------------------------------------
170 */
171
172 void *Safe_calloc(size_t Elements,size_t Size)
173
174 {
175 void *NewPtr ;
176
177 NewPtr = MALLOC(Elements*Size) ;
178 #if TRACEMALLOC
179  _log(Elements*Size);
180 #endif
181  
182 if (!NewPtr)
183   {
184   printf("ERROR - No more memory\n") ;
185 /*  werror(E_OUT_OF_MEM,__FILE__,Size);*/
186   exit (1);
187   }
188
189  memset(NewPtr, 0, Elements*Size);
190
191 return NewPtr ;
192 }
193 /*
194 -------------------------------------------------------------------------------
195 Safe_malloc - Allocate a block of memory from the application heap
196 and checking for out of memory errors.
197
198 -------------------------------------------------------------------------------
199 */
200
201 void *Safe_malloc(size_t Size)
202
203 {
204 void *NewPtr ;
205
206 NewPtr = MALLOC(Size) ;
207
208 #if TRACEMALLOC
209  _log(Size);
210 #endif
211
212 if (!NewPtr)
213   {
214   printf("ERROR - No more memory\n") ;
215 /*  werror(E_OUT_OF_MEM,__FILE__,Size);*/
216   exit (1);
217   }
218
219 return NewPtr ;
220 }
221
222 void *Safe_alloc(size_t Size)
223 {
224   return Safe_calloc(1, Size);
225 }
226
227 void Safe_free(void *p)
228 {
229   FREE(p);
230 }
231
232 char *Safe_strdup(const char *sz)
233 {
234   char *pret;
235   assert(sz);
236
237   pret = Safe_alloc(strlen(sz) +1);
238   strcpy(pret, sz);
239
240   return pret;
241 }
242
243 void *traceAlloc(allocTrace *ptrace, void *p)
244 {
245   assert(ptrace);
246   assert(p);
247
248   /* Also handles where max == 0 */
249   if (ptrace->num == ptrace->max)
250     {
251       /* Add an offset to handle max == 0 */
252       ptrace->max = (ptrace->max+2)*2;
253       ptrace->palloced = Safe_realloc(ptrace->palloced, ptrace->max * sizeof(*ptrace->palloced));
254     }
255   ptrace->palloced[ptrace->num++] = p;
256
257   return p;
258 }
259
260 void freeTrace(allocTrace *ptrace)
261 {
262   int i;
263   assert(ptrace);
264
265   for (i = 0; i < ptrace->num; i++)
266     {
267       Safe_free(ptrace->palloced[i]);
268     }
269   ptrace->num = 0;
270
271   Safe_free(ptrace->palloced);
272   ptrace->palloced = NULL;
273   ptrace->max = 0;
274 }
275