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