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