1 /* Boolector: Satisfiability Modulo Theories (SMT) solver.
2 *
3 * Copyright (C) 2007-2021 by the authors listed in the AUTHORS file.
4 *
5 * This file is part of Boolector.
6 * See COPYING for more information on using this software.
7 */
8
9 #include "btormem.h"
10
11 #include "btorabort.h"
12
13 #include <assert.h>
14 #include <stdarg.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 /*------------------------------------------------------------------------*/
20
21 #define ADJUST() \
22 do \
23 { \
24 if (mm->maxallocated < mm->allocated) mm->maxallocated = mm->allocated; \
25 } while (0)
26
27 #define SAT_ADJUST() \
28 do \
29 { \
30 if (mm->sat_maxallocated < mm->sat_allocated) \
31 mm->sat_maxallocated = mm->sat_allocated; \
32 } while (0)
33
34 /*------------------------------------------------------------------------*/
35 /* This enables logging of all memory allocations.
36 */
37 #if 0
38 #define BTOR_LOG_MEM(FMT, ARGS...) \
39 do \
40 { \
41 fputs ("[btorlogmem] ", stdout); \
42 printf (FMT, ##ARGS); \
43 fflush (stdout); \
44 } while (0)
45 #else
46 #define BTOR_LOG_MEM(...) \
47 do \
48 { \
49 } while (0)
50 #endif
51
52 /*------------------------------------------------------------------------*/
53
54 BtorMemMgr *
btor_mem_mgr_new(void)55 btor_mem_mgr_new (void)
56 {
57 BtorMemMgr *mm = (BtorMemMgr *) malloc (sizeof (BtorMemMgr));
58 BTOR_ABORT (!mm, "out of memory in 'btor_mem_mgr_new'");
59 mm->allocated = 0;
60 mm->maxallocated = 0;
61 mm->sat_allocated = 0;
62 mm->sat_maxallocated = 0;
63 return mm;
64 }
65
66 void *
btor_mem_malloc(BtorMemMgr * mm,size_t size)67 btor_mem_malloc (BtorMemMgr *mm, size_t size)
68 {
69 void *result;
70 if (!size) return 0;
71 assert (mm);
72 result = malloc (size);
73 BTOR_ABORT (!result, "out of memory in 'btor_mem_malloc'");
74 mm->allocated += size;
75 ADJUST ();
76 BTOR_LOG_MEM ("%p malloc %10ld\n", result, size);
77 return result;
78 }
79
80 void *
btor_mem_sat_malloc(BtorMemMgr * mm,size_t size)81 btor_mem_sat_malloc (BtorMemMgr *mm, size_t size)
82 {
83 void *result;
84 if (!size) return 0;
85 assert (mm);
86 result = malloc (size);
87 BTOR_ABORT (!result, "out of memory in 'btor_mem_sat_malloc'");
88 mm->sat_allocated += size;
89 SAT_ADJUST ();
90 return result;
91 }
92
93 void *
btor_mem_realloc(BtorMemMgr * mm,void * p,size_t old_size,size_t new_size)94 btor_mem_realloc (BtorMemMgr *mm, void *p, size_t old_size, size_t new_size)
95 {
96 void *result;
97 assert (mm);
98 assert (!p == !old_size);
99 assert (mm->allocated >= old_size);
100 BTOR_LOG_MEM ("%p free %10ld (realloc)\n", p, old_size);
101 result = realloc (p, new_size);
102 BTOR_ABORT (!result, "out of memory in 'btor_mem_realloc'");
103 mm->allocated -= old_size;
104 mm->allocated += new_size;
105 ADJUST ();
106 BTOR_LOG_MEM ("%p malloc %10ld (realloc)\n", result, new_size);
107 return result;
108 }
109
110 void *
btor_mem_sat_realloc(BtorMemMgr * mm,void * p,size_t old_size,size_t new_size)111 btor_mem_sat_realloc (BtorMemMgr *mm, void *p, size_t old_size, size_t new_size)
112 {
113 void *result;
114 assert (mm);
115 assert (!p == !old_size);
116 assert (mm->sat_allocated >= old_size);
117 result = realloc (p, new_size);
118 BTOR_ABORT (!result, "out of memory in 'btor_mem_sat_realloc'");
119 mm->sat_allocated -= old_size;
120 mm->sat_allocated += new_size;
121 SAT_ADJUST ();
122 return result;
123 }
124
125 void *
btor_mem_calloc(BtorMemMgr * mm,size_t nobj,size_t size)126 btor_mem_calloc (BtorMemMgr *mm, size_t nobj, size_t size)
127 {
128 size_t bytes = nobj * size;
129 void *result;
130 assert (mm);
131 result = calloc (nobj, size);
132 BTOR_ABORT (!result, "out of memory in 'btor_mem_calloc'");
133 mm->allocated += bytes;
134 ADJUST ();
135 BTOR_LOG_MEM ("%p malloc %10ld (calloc)\n", result, bytes);
136 return result;
137 }
138
139 void
btor_mem_free(BtorMemMgr * mm,void * p,size_t freed)140 btor_mem_free (BtorMemMgr *mm, void *p, size_t freed)
141 {
142 assert (mm);
143 assert (!p == !freed);
144 assert (mm->allocated >= freed);
145 mm->allocated -= freed;
146 BTOR_LOG_MEM ("%p free %10ld\n", p, freed);
147 free (p);
148 }
149
150 void
btor_mem_sat_free(BtorMemMgr * mm,void * p,size_t freed)151 btor_mem_sat_free (BtorMemMgr *mm, void *p, size_t freed)
152 {
153 assert (mm);
154 if (p) mm->sat_allocated -= freed;
155 free (p);
156 }
157
158 char *
btor_mem_strdup(BtorMemMgr * mm,const char * str)159 btor_mem_strdup (BtorMemMgr *mm, const char *str)
160 {
161 char *res;
162
163 if (str)
164 {
165 res = btor_mem_malloc (mm, strlen (str) + 1);
166 strcpy (res, str);
167 }
168 else
169 res = 0;
170
171 return res;
172 }
173
174 void
btor_mem_freestr(BtorMemMgr * mm,char * str)175 btor_mem_freestr (BtorMemMgr *mm, char *str)
176 {
177 if (str) btor_mem_free (mm, str, strlen (str) + 1);
178 }
179
180 void
btor_mem_mgr_delete(BtorMemMgr * mm)181 btor_mem_mgr_delete (BtorMemMgr *mm)
182 {
183 assert (mm);
184 assert (getenv ("BTORLEAK") || getenv ("BTORLEAKMEM") || !mm->allocated);
185 free (mm);
186 }
187
188 size_t
btor_mem_parse_error_msg_length(const char * name,const char * fmt,va_list ap)189 btor_mem_parse_error_msg_length (const char *name, const char *fmt, va_list ap)
190 {
191 /* Additional characters for:
192
193 "<name>:<lineno>:[<columno>:] "
194
195 */
196 size_t bytes = strlen (name) + 25;
197 const char *p;
198
199 for (p = fmt; *p; p++)
200 {
201 if (*p == '%')
202 {
203 p++;
204 assert (*p);
205 if (*p == 'c')
206 {
207 (void) va_arg (ap, int32_t);
208 bytes += 1;
209 }
210 else if (*p == 'd' || *p == 'u')
211 {
212 (void) va_arg (ap, uint32_t);
213 bytes += 12;
214 }
215 else
216 {
217 assert (*p == 's');
218 bytes += strlen (va_arg (ap, const char *));
219 }
220 }
221 else
222 bytes++;
223 }
224
225 return bytes;
226 }
227
228 char *
btor_mem_parse_error_msg(BtorMemMgr * mem,const char * name,int32_t lineno,int32_t columno,const char * fmt,va_list ap,size_t bytes)229 btor_mem_parse_error_msg (BtorMemMgr *mem,
230 const char *name,
231 int32_t lineno,
232 int32_t columno,
233 const char *fmt,
234 va_list ap,
235 size_t bytes)
236 {
237 char *res;
238 char *tmp;
239
240 tmp = btor_mem_malloc (mem, bytes);
241 if (columno > 0)
242 sprintf (tmp, "%s:%d:%d: ", name, lineno, columno);
243 else
244 sprintf (tmp, "%s:%d: ", name, lineno);
245 assert (strlen (tmp) + 1 < bytes);
246 vsprintf (tmp + strlen (tmp), fmt, ap);
247 res = btor_mem_strdup (mem, tmp);
248 btor_mem_free (mem, tmp, bytes);
249
250 return res;
251 }
252