Don't use memset(3) after `GC_MALLOC ()' calls.
[bpt/guile.git] / libguile / gc-malloc.c
CommitLineData
2fa901a5 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
c7743d02 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
c7743d02 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
c7743d02 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
c7743d02
HWN
18
19
20\f
dbb605f5 21#ifdef HAVE_CONFIG_H
132fa21f
RB
22# include <config.h>
23#endif
24
c7743d02
HWN
25#include <stdio.h>
26#include <errno.h>
27#include <string.h>
28
29#ifdef __ia64__
30#include <ucontext.h>
31extern unsigned long * __libc_ia64_register_backing_store_base;
32#endif
33
34#include "libguile/_scm.h"
35#include "libguile/eval.h"
36#include "libguile/stime.h"
37#include "libguile/stackchk.h"
38#include "libguile/struct.h"
39#include "libguile/smob.h"
2fa901a5 40#include "libguile/arrays.h"
c7743d02
HWN
41#include "libguile/async.h"
42#include "libguile/ports.h"
43#include "libguile/root.h"
44#include "libguile/strings.h"
45#include "libguile/vectors.h"
46#include "libguile/weaks.h"
47#include "libguile/hashtab.h"
48#include "libguile/tags.h"
49
50#include "libguile/validate.h"
51#include "libguile/deprecation.h"
52#include "libguile/gc.h"
53
54#include "libguile/private-gc.h"
55
56#ifdef GUILE_DEBUG_MALLOC
57#include "libguile/debug-malloc.h"
58#endif
59
60#ifdef HAVE_MALLOC_H
61#include <malloc.h>
62#endif
63
64#ifdef HAVE_UNISTD_H
65#include <unistd.h>
66#endif
67
68/*
69 INIT_MALLOC_LIMIT is the initial amount of malloc usage which will
70 trigger a GC.
71
72 After startup (at the guile> prompt), we have approximately 100k of
73 alloced memory, which won't go away on GC. Let's set the init such
74 that we get a nice yield on the next allocation:
75*/
c2cbcc57 76#define SCM_DEFAULT_INIT_MALLOC_LIMIT 200*1024
c7743d02
HWN
77#define SCM_DEFAULT_MALLOC_MINYIELD 40
78
61ef9c1f 79/* #define DEBUGINFO */
c7743d02 80
c7743d02
HWN
81
82\f
83/* Function for non-cell memory management.
84 */
85
c7743d02
HWN
86void *
87scm_realloc (void *mem, size_t size)
88{
89 void *ptr;
90
91 SCM_SYSCALL (ptr = realloc (mem, size));
92 if (ptr)
93 return ptr;
94
26224b3f
LC
95 /* Time is hard: trigger a full, ``stop-the-world'' GC, and try again. */
96 GC_gcollect ();
b17e0ac3 97
c7743d02
HWN
98 SCM_SYSCALL (ptr = realloc (mem, size));
99 if (ptr)
100 return ptr;
101
102 scm_memory_error ("realloc");
103}
104
39e8f371
HWN
105void *
106scm_malloc (size_t sz)
107{
108 return scm_realloc (NULL, sz);
109}
ba1b2226
HWN
110
111/*
112 Hmm. Should we use the C convention for arguments (i.e. N_ELTS,
113 SIZEOF_ELT)? --hwn
114 */
115void *
116scm_calloc (size_t sz)
117{
1383773b
HWN
118 void * ptr;
119
120 /*
121 By default, try to use calloc, as it is likely more efficient than
122 calling memset by hand.
123 */
fb50ef08 124 SCM_SYSCALL (ptr = calloc (sz, 1));
1383773b
HWN
125 if (ptr)
126 return ptr;
26224b3f 127
1383773b 128 ptr = scm_realloc (NULL, sz);
ba1b2226
HWN
129 memset (ptr, 0x0, sz);
130 return ptr;
131}
132
39e8f371 133
c7743d02
HWN
134char *
135scm_strndup (const char *str, size_t n)
136{
fb50ef08 137 char *dst = scm_malloc (n + 1);
c7743d02
HWN
138 memcpy (dst, str, n);
139 dst[n] = 0;
140 return dst;
141}
142
143char *
144scm_strdup (const char *str)
145{
146 return scm_strndup (str, strlen (str));
147}
148
b17e0ac3 149
cbfe8e62
HWN
150
151void
152scm_gc_register_collectable_memory (void *mem, size_t size, const char *what)
153{
c5018a2b 154 /* Nothing to do. */
c7743d02
HWN
155#ifdef GUILE_DEBUG_MALLOC
156 if (mem)
26224b3f 157 scm_malloc_register (mem);
c7743d02
HWN
158#endif
159}
160
cbfe8e62 161
c7743d02
HWN
162void
163scm_gc_unregister_collectable_memory (void *mem, size_t size, const char *what)
164{
c5018a2b 165 /* Nothing to do. */
c7743d02
HWN
166#ifdef GUILE_DEBUG_MALLOC
167 if (mem)
168 scm_malloc_unregister (mem);
169#endif
170}
171
c5018a2b
LC
172/* Allocate SIZE bytes of memory whose contents should not be scanned for
173 pointers (useful, e.g., for strings). */
174void *
175scm_gc_malloc_pointerless (size_t size, const char *what)
176{
177 return GC_MALLOC_ATOMIC (size);
178}
179
c7743d02
HWN
180void *
181scm_gc_malloc (size_t size, const char *what)
182{
183 /*
184 The straightforward implementation below has the problem
185 that it might call the GC twice, once in scm_malloc and then
186 again in scm_gc_register_collectable_memory. We don't really
187 want the second GC since it will not find new garbage.
188
1f584400 189 Note: this is a theoretical peeve. In reality, malloc () never
c7743d02
HWN
190 returns NULL. Usually, memory is overcommitted, and when you try
191 to write it the program is killed with signal 11. --hwn
192 */
193
ea4f8ea1
LC
194 void *ptr;
195
196 if (size == 0)
197 /* `GC_MALLOC ()' doesn't handle zero. */
198 size = sizeof (void *);
199
200 ptr = GC_MALLOC (size);
201
c7743d02
HWN
202 return ptr;
203}
204
39e8f371
HWN
205void *
206scm_gc_calloc (size_t size, const char *what)
207{
b1f6293e
LC
208 /* `GC_MALLOC ()' always returns a zeroed buffer. */
209 return scm_gc_malloc (size, what);
39e8f371
HWN
210}
211
212
c7743d02
HWN
213void *
214scm_gc_realloc (void *mem, size_t old_size, size_t new_size, const char *what)
215{
53f18a0d
KR
216 void *ptr;
217
26224b3f 218 ptr = GC_REALLOC (mem, new_size);
cbfe8e62
HWN
219
220#ifdef GUILE_DEBUG_MALLOC
221 if (mem)
222 scm_malloc_reregister (mem, ptr, what);
223#endif
26224b3f 224
c7743d02
HWN
225 return ptr;
226}
227
228void
229scm_gc_free (void *mem, size_t size, const char *what)
230{
231 scm_gc_unregister_collectable_memory (mem, size, what);
26224b3f 232 GC_FREE (mem);
c7743d02
HWN
233}
234
235char *
236scm_gc_strndup (const char *str, size_t n, const char *what)
237{
e7acfa88 238 char *dst = GC_MALLOC_ATOMIC (n + 1);
c7743d02
HWN
239 memcpy (dst, str, n);
240 dst[n] = 0;
241 return dst;
242}
243
244char *
245scm_gc_strdup (const char *str, const char *what)
246{
247 return scm_gc_strndup (str, strlen (str), what);
248}
249
250#if SCM_ENABLE_DEPRECATED == 1
251
252/* {Deprecated front end to malloc}
253 *
254 * scm_must_malloc, scm_must_realloc, scm_must_free, scm_done_malloc,
255 * scm_done_free
256 *
257 * These functions provide services comparable to malloc, realloc, and
258 * free. They should be used when allocating memory that will be under
259 * control of the garbage collector, i.e., if the memory may be freed
260 * during garbage collection.
261 *
262 * They are deprecated because they weren't really used the way
263 * outlined above, and making sure to return the right amount from
264 * smob free routines was sometimes difficult when dealing with nested
265 * data structures. We basically want everybody to review their code
266 * and use the more symmetrical scm_gc_malloc/scm_gc_free functions
267 * instead. In some cases, where scm_must_malloc has been used
268 * incorrectly (i.e. for non-GC-able memory), use scm_malloc/free.
269 */
270
271void *
272scm_must_malloc (size_t size, const char *what)
273{
274 scm_c_issue_deprecation_warning
275 ("scm_must_malloc is deprecated. "
276 "Use scm_gc_malloc and scm_gc_free instead.");
277
278 return scm_gc_malloc (size, what);
279}
280
281void *
282scm_must_realloc (void *where,
283 size_t old_size,
284 size_t size,
285 const char *what)
286{
287 scm_c_issue_deprecation_warning
288 ("scm_must_realloc is deprecated. "
289 "Use scm_gc_realloc and scm_gc_free instead.");
290
291 return scm_gc_realloc (where, old_size, size, what);
292}
293
294char *
295scm_must_strndup (const char *str, size_t length)
296{
297 scm_c_issue_deprecation_warning
298 ("scm_must_strndup is deprecated. "
299 "Use scm_gc_strndup and scm_gc_free instead.");
300
301 return scm_gc_strndup (str, length, "string");
302}
303
304char *
305scm_must_strdup (const char *str)
306{
307 scm_c_issue_deprecation_warning
308 ("scm_must_strdup is deprecated. "
309 "Use scm_gc_strdup and scm_gc_free instead.");
310
311 return scm_gc_strdup (str, "string");
312}
313
314void
315scm_must_free (void *obj)
316#define FUNC_NAME "scm_must_free"
317{
318 scm_c_issue_deprecation_warning
319 ("scm_must_free is deprecated. "
320 "Use scm_gc_malloc and scm_gc_free instead.");
321
322#ifdef GUILE_DEBUG_MALLOC
323 scm_malloc_unregister (obj);
324#endif
325 if (obj)
326 free (obj);
327 else
be3ff021
HWN
328 {
329 fprintf (stderr,"freeing NULL pointer");
330 abort ();
331 }
c7743d02
HWN
332}
333#undef FUNC_NAME
334
335
336void
337scm_done_malloc (long size)
338{
339 scm_c_issue_deprecation_warning
340 ("scm_done_malloc is deprecated. "
341 "Use scm_gc_register_collectable_memory instead.");
342
4cd3853f
KR
343 if (size >= 0)
344 scm_gc_register_collectable_memory (NULL, size, "foreign mallocs");
345 else
346 scm_gc_unregister_collectable_memory (NULL, -size, "foreign mallocs");
c7743d02
HWN
347}
348
349void
350scm_done_free (long size)
351{
352 scm_c_issue_deprecation_warning
353 ("scm_done_free is deprecated. "
354 "Use scm_gc_unregister_collectable_memory instead.");
355
4cd3853f
KR
356 if (size >= 0)
357 scm_gc_unregister_collectable_memory (NULL, size, "foreign mallocs");
358 else
359 scm_gc_register_collectable_memory (NULL, -size, "foreign mallocs");
c7743d02
HWN
360}
361
362#endif /* SCM_ENABLE_DEPRECATED == 1 */