switch off debugging flag that was mistakenly left on
[bpt/guile.git] / libguile / gc.c
CommitLineData
ec7f624d 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
a00c95d9 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.
a00c95d9 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.
a00c95d9 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 */
1bbd0b84 18
37ddcaf6
MD
19/* #define DEBUGINFO */
20
dbb605f5 21#ifdef HAVE_CONFIG_H
aa54a9b0
RB
22# include <config.h>
23#endif
56495472 24
e7bca227
LC
25#include "libguile/gen-scmconfig.h"
26
0f2d19dd 27#include <stdio.h>
e6e2e95a 28#include <errno.h>
783e7774 29#include <string.h>
6360beb2 30#include <math.h>
e6e2e95a 31
3ec17f28
LC
32#ifdef __ia64__
33#include <ucontext.h>
34extern unsigned long * __libc_ia64_register_backing_store_base;
35#endif
36
a0599745 37#include "libguile/_scm.h"
0a7a7445 38#include "libguile/eval.h"
a0599745
MD
39#include "libguile/stime.h"
40#include "libguile/stackchk.h"
41#include "libguile/struct.h"
a0599745 42#include "libguile/smob.h"
2fa901a5 43#include "libguile/arrays.h"
a0599745
MD
44#include "libguile/async.h"
45#include "libguile/ports.h"
46#include "libguile/root.h"
47#include "libguile/strings.h"
48#include "libguile/vectors.h"
801cb5e7 49#include "libguile/weaks.h"
686765af 50#include "libguile/hashtab.h"
ecf470a2 51#include "libguile/tags.h"
a0599745 52
c8a1bdc4 53#include "libguile/private-gc.h"
a0599745 54#include "libguile/validate.h"
1be6b49c 55#include "libguile/deprecation.h"
a0599745 56#include "libguile/gc.h"
9de87eea 57#include "libguile/dynwind.h"
fce59c93 58
1c44468d 59#include "libguile/bdw-gc.h"
a82e7953 60
cc3546b0
AW
61/* For GC_set_start_callback. */
62#include <gc/gc_mark.h>
63
bc9d9bb2 64#ifdef GUILE_DEBUG_MALLOC
a0599745 65#include "libguile/debug-malloc.h"
bc9d9bb2
MD
66#endif
67
0f2d19dd 68#ifdef HAVE_MALLOC_H
95b88819 69#include <malloc.h>
0f2d19dd
JB
70#endif
71
72#ifdef HAVE_UNISTD_H
95b88819 73#include <unistd.h>
0f2d19dd
JB
74#endif
75
eae33935 76/* Set this to != 0 if every cell that is accessed shall be checked:
61045190 77 */
eab1b259
HWN
78int scm_debug_cell_accesses_p = 0;
79int scm_expensive_debug_cell_accesses_p = 0;
406c7d90 80
e81d98ec
DH
81/* Set this to 0 if no additional gc's shall be performed, otherwise set it to
82 * the number of cell accesses after which a gc shall be called.
83 */
eab1b259 84int scm_debug_cells_gc_interval = 0;
e81d98ec 85
f0d1bacd 86#if SCM_ENABLE_DEPRECATED == 1
acbccb0c
LC
87/* Hash table that keeps a reference to objects the user wants to protect from
88 garbage collection. It could arguably be private but applications have come
89 to rely on it (e.g., Lilypond 2.13.9). */
90SCM scm_protects;
f0d1bacd
AW
91#else
92static SCM scm_protects;
93#endif
e7efe8e7 94
eab1b259
HWN
95#if (SCM_DEBUG_CELL_ACCESSES == 1)
96
97
98/*
99
100 Assert that the given object is a valid reference to a valid cell. This
101 test involves to determine whether the object is a cell pointer, whether
102 this pointer actually points into a heap segment and whether the cell
103 pointed to is not a free cell. Further, additional garbage collections may
104 get executed after a user defined number of cell accesses. This helps to
105 find places in the C code where references are dropped for extremely short
106 periods.
107
108*/
406c7d90 109void
eab1b259 110scm_i_expensive_validation_check (SCM cell)
406c7d90 111{
eab1b259
HWN
112 /* If desired, perform additional garbage collections after a user
113 * defined number of cell accesses.
114 */
115 if (scm_debug_cells_gc_interval)
116 {
117 static unsigned int counter = 0;
61045190 118
eab1b259
HWN
119 if (counter != 0)
120 {
121 --counter;
122 }
123 else
124 {
125 counter = scm_debug_cells_gc_interval;
b17e0ac3 126 scm_gc ();
eab1b259
HWN
127 }
128 }
129}
130
8c93b597
LC
131/* Whether cell validation is already running. */
132static int scm_i_cell_validation_already_running = 0;
133
eab1b259
HWN
134void
135scm_assert_cell_valid (SCM cell)
136{
137 if (!scm_i_cell_validation_already_running && scm_debug_cell_accesses_p)
406c7d90 138 {
eab1b259 139 scm_i_cell_validation_already_running = 1; /* set to avoid recursion */
406c7d90 140
c8a1bdc4 141 /*
eab1b259
HWN
142 During GC, no user-code should be run, and the guile core
143 should use non-protected accessors.
144 */
c8a1bdc4 145 if (scm_gc_running_p)
eab1b259 146 return;
c8a1bdc4
HWN
147
148 /*
eab1b259
HWN
149 Only scm_in_heap_p and rescanning the heap is wildly
150 expensive.
151 */
152 if (scm_expensive_debug_cell_accesses_p)
153 scm_i_expensive_validation_check (cell);
b4246e5b 154
eab1b259 155 scm_i_cell_validation_already_running = 0; /* re-enable */
406c7d90
DH
156 }
157}
158
159
eab1b259 160
406c7d90
DH
161SCM_DEFINE (scm_set_debug_cell_accesses_x, "set-debug-cell-accesses!", 1, 0, 0,
162 (SCM flag),
1e6808ea 163 "If @var{flag} is @code{#f}, cell access checking is disabled.\n"
eab1b259 164 "If @var{flag} is @code{#t}, cheap cell access checking is enabled,\n"
e81d98ec 165 "but no additional calls to garbage collection are issued.\n"
eab1b259 166 "If @var{flag} is a number, strict cell access checking is enabled,\n"
e81d98ec
DH
167 "with an additional garbage collection after the given\n"
168 "number of cell accesses.\n"
1e6808ea
MG
169 "This procedure only exists when the compile-time flag\n"
170 "@code{SCM_DEBUG_CELL_ACCESSES} was set to 1.")
406c7d90
DH
171#define FUNC_NAME s_scm_set_debug_cell_accesses_x
172{
7888309b 173 if (scm_is_false (flag))
eab1b259
HWN
174 {
175 scm_debug_cell_accesses_p = 0;
176 }
bc36d050 177 else if (scm_is_eq (flag, SCM_BOOL_T))
eab1b259
HWN
178 {
179 scm_debug_cells_gc_interval = 0;
180 scm_debug_cell_accesses_p = 1;
181 scm_expensive_debug_cell_accesses_p = 0;
182 }
e11e83f3 183 else
eab1b259 184 {
e11e83f3 185 scm_debug_cells_gc_interval = scm_to_signed_integer (flag, 0, INT_MAX);
eab1b259
HWN
186 scm_debug_cell_accesses_p = 1;
187 scm_expensive_debug_cell_accesses_p = 1;
188 }
406c7d90
DH
189 return SCM_UNSPECIFIED;
190}
191#undef FUNC_NAME
0f2d19dd 192
ecf470a2 193
c8a1bdc4 194#endif /* SCM_DEBUG_CELL_ACCESSES == 1 */
0f2d19dd
JB
195
196\f
14294ce0 197
6360beb2
AW
198/* Compatibility. */
199
14294ce0
AW
200#ifndef HAVE_GC_GET_HEAP_USAGE_SAFE
201static void
202GC_get_heap_usage_safe (GC_word *pheap_size, GC_word *pfree_bytes,
203 GC_word *punmapped_bytes, GC_word *pbytes_since_gc,
204 GC_word *ptotal_bytes)
205{
206 *pheap_size = GC_get_heap_size ();
207 *pfree_bytes = GC_get_free_bytes ();
208 *punmapped_bytes = GC_get_unmapped_bytes ();
209 *pbytes_since_gc = GC_get_bytes_since_gc ();
210 *ptotal_bytes = GC_get_total_bytes ();
211}
212#endif
213
6360beb2
AW
214#ifndef HAVE_GC_GET_FREE_SPACE_DIVISOR
215static GC_word
216GC_get_free_space_divisor (void)
217{
218 return GC_free_space_divisor;
219}
220#endif
221
14294ce0 222\f
26224b3f
LC
223/* Hooks. */
224scm_t_c_hook scm_before_gc_c_hook;
225scm_t_c_hook scm_before_mark_c_hook;
226scm_t_c_hook scm_before_sweep_c_hook;
227scm_t_c_hook scm_after_sweep_c_hook;
228scm_t_c_hook scm_after_gc_c_hook;
945fec60 229
0f2d19dd 230
0fbdbe6c
AW
231static void
232run_before_gc_c_hook (void)
233{
234 scm_c_hook_run (&scm_before_gc_c_hook, NULL);
235}
236
237
0f2d19dd
JB
238/* GC Statistics Keeping
239 */
b74e86cf 240unsigned long scm_gc_ports_collected = 0;
00b6ef23
AW
241static long gc_time_taken = 0;
242static long gc_start_time = 0;
243
6360beb2
AW
244static unsigned long free_space_divisor;
245static unsigned long minimum_free_space_divisor;
246static double target_free_space_divisor;
b74e86cf 247
915b3f9f 248static unsigned long protected_obj_count = 0;
c2cbcc57 249
0f2d19dd 250
17ab1dc3 251SCM_SYMBOL (sym_gc_time_taken, "gc-time-taken");
915b3f9f
LC
252SCM_SYMBOL (sym_heap_size, "heap-size");
253SCM_SYMBOL (sym_heap_free_size, "heap-free-size");
254SCM_SYMBOL (sym_heap_total_allocated, "heap-total-allocated");
17ab1dc3 255SCM_SYMBOL (sym_heap_allocated_since_gc, "heap-allocated-since-gc");
7eec4c37 256SCM_SYMBOL (sym_protected_objects, "protected-objects");
17ab1dc3 257SCM_SYMBOL (sym_times, "gc-times");
cf2d30f6 258
d3dd80ab 259
0f2d19dd
JB
260/* {Scheme Interface to GC}
261 */
1367aa5e
HWN
262static SCM
263tag_table_to_type_alist (void *closure, SCM key, SCM val, SCM acc)
264{
8fecbb19 265 if (scm_is_integer (key))
8a00ba71 266 {
3e2073bd 267 int c_tag = scm_to_int (key);
8fecbb19
HWN
268
269 char const * name = scm_i_tag_name (c_tag);
270 if (name != NULL)
271 {
272 key = scm_from_locale_string (name);
273 }
274 else
275 {
276 char s[100];
277 sprintf (s, "tag %d", c_tag);
278 key = scm_from_locale_string (s);
279 }
8a00ba71 280 }
8fecbb19 281
1367aa5e
HWN
282 return scm_cons (scm_cons (key, val), acc);
283}
284
285SCM_DEFINE (scm_gc_live_object_stats, "gc-live-object-stats", 0, 0, 0,
286 (),
287 "Return an alist of statistics of the current live objects. ")
288#define FUNC_NAME s_scm_gc_live_object_stats
289{
290 SCM tab = scm_make_hash_table (scm_from_int (57));
b01532af
NJ
291 SCM alist;
292
b01532af 293 alist
1367aa5e
HWN
294 = scm_internal_hash_fold (&tag_table_to_type_alist, NULL, SCM_EOL, tab);
295
296 return alist;
297}
298#undef FUNC_NAME
299
c2cbcc57 300extern int scm_gc_malloc_yield_percentage;
a00c95d9 301SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
1bbd0b84 302 (),
1e6808ea 303 "Return an association list of statistics about Guile's current\n"
c8a1bdc4 304 "use of storage.\n")
1bbd0b84 305#define FUNC_NAME s_scm_gc_stats
0f2d19dd 306{
0f2d19dd 307 SCM answer;
14294ce0 308 GC_word heap_size, free_bytes, unmapped_bytes, bytes_since_gc, total_bytes;
915b3f9f 309 size_t gc_times;
4c9419ac 310
14294ce0
AW
311 GC_get_heap_usage_safe (&heap_size, &free_bytes, &unmapped_bytes,
312 &bytes_since_gc, &total_bytes);
313 gc_times = GC_gc_no;
fca43887 314
b9bd8526 315 answer =
00b6ef23 316 scm_list_n (scm_cons (sym_gc_time_taken, scm_from_long (gc_time_taken)),
915b3f9f
LC
317 scm_cons (sym_heap_size, scm_from_size_t (heap_size)),
318 scm_cons (sym_heap_free_size, scm_from_size_t (free_bytes)),
319 scm_cons (sym_heap_total_allocated,
320 scm_from_size_t (total_bytes)),
17ab1dc3
AW
321 scm_cons (sym_heap_allocated_since_gc,
322 scm_from_size_t (bytes_since_gc)),
915b3f9f
LC
323 scm_cons (sym_protected_objects,
324 scm_from_ulong (protected_obj_count)),
325 scm_cons (sym_times, scm_from_size_t (gc_times)),
b9bd8526 326 SCM_UNDEFINED);
fca43887 327
c8a1bdc4 328 return answer;
0f2d19dd 329}
c8a1bdc4 330#undef FUNC_NAME
0f2d19dd 331
539b08a4 332
7f9ec18a
LC
333SCM_DEFINE (scm_gc_dump, "gc-dump", 0, 0, 0,
334 (void),
335 "Dump information about the garbage collector's internal data "
336 "structures and memory usage to the standard output.")
337#define FUNC_NAME s_scm_gc_dump
338{
339 GC_dump ();
340
341 return SCM_UNSPECIFIED;
342}
343#undef FUNC_NAME
344
acf4331f 345
c8a1bdc4
HWN
346SCM_DEFINE (scm_object_address, "object-address", 1, 0, 0,
347 (SCM obj),
348 "Return an integer that for the lifetime of @var{obj} is uniquely\n"
349 "returned by this function for @var{obj}")
350#define FUNC_NAME s_scm_object_address
c68296f8 351{
b9bd8526 352 return scm_from_ulong (SCM_UNPACK (obj));
c68296f8 353}
c8a1bdc4 354#undef FUNC_NAME
c68296f8 355
1be6b49c 356
915b3f9f
LC
357SCM_DEFINE (scm_gc_disable, "gc-disable", 0, 0, 0,
358 (),
359 "Disables the garbage collector. Nested calls are permitted. "
360 "GC is re-enabled once @code{gc-enable} has been called the "
361 "same number of times @code{gc-disable} was called.")
362#define FUNC_NAME s_scm_gc_disable
363{
364 GC_disable ();
365 return SCM_UNSPECIFIED;
366}
367#undef FUNC_NAME
368
369SCM_DEFINE (scm_gc_enable, "gc-enable", 0, 0, 0,
370 (),
371 "Enables the garbage collector.")
372#define FUNC_NAME s_scm_gc_enable
373{
374 GC_enable ();
375 return SCM_UNSPECIFIED;
376}
377#undef FUNC_NAME
378
379
c8a1bdc4
HWN
380SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
381 (),
382 "Scans all of SCM objects and reclaims for further use those that are\n"
383 "no longer accessible.")
384#define FUNC_NAME s_scm_gc
385{
b17e0ac3 386 scm_i_gc ("call");
c8a1bdc4 387 return SCM_UNSPECIFIED;
9d47a1e6 388}
c8a1bdc4 389#undef FUNC_NAME
9d47a1e6 390
c8a1bdc4 391void
b17e0ac3 392scm_i_gc (const char *what)
c8a1bdc4 393{
66b229d5
AW
394#ifndef HAVE_GC_SET_START_CALLBACK
395 run_before_gc_c_hook ();
396#endif
26224b3f 397 GC_gcollect ();
eab1b259 398}
0f2d19dd 399
4c7016dc 400
0f2d19dd
JB
401\f
402/* {GC Protection Helper Functions}
403 */
404
405
5d2b97cd
DH
406/*
407 * If within a function you need to protect one or more scheme objects from
408 * garbage collection, pass them as parameters to one of the
409 * scm_remember_upto_here* functions below. These functions don't do
410 * anything, but since the compiler does not know that they are actually
411 * no-ops, it will generate code that calls these functions with the given
412 * parameters. Therefore, you can be sure that the compiler will keep those
413 * scheme values alive (on the stack or in a register) up to the point where
414 * scm_remember_upto_here* is called. In other words, place the call to
592996c9 415 * scm_remember_upto_here* _behind_ the last code in your function, that
5d2b97cd
DH
416 * depends on the scheme object to exist.
417 *
8c494e99
DH
418 * Example: We want to make sure that the string object str does not get
419 * garbage collected during the execution of 'some_function' in the code
420 * below, because otherwise the characters belonging to str would be freed and
5d2b97cd
DH
421 * 'some_function' might access freed memory. To make sure that the compiler
422 * keeps str alive on the stack or in a register such that it is visible to
423 * the conservative gc we add the call to scm_remember_upto_here_1 _after_ the
424 * call to 'some_function'. Note that this would not be necessary if str was
425 * used anyway after the call to 'some_function'.
eb01cb64 426 * char *chars = scm_i_string_chars (str);
5d2b97cd
DH
427 * some_function (chars);
428 * scm_remember_upto_here_1 (str); // str will be alive up to this point.
429 */
430
9e1569bd
KR
431/* Remove any macro versions of these while defining the functions.
432 Functions are always included in the library, for upward binary
433 compatibility and in case combinations of GCC and non-GCC are used. */
434#undef scm_remember_upto_here_1
435#undef scm_remember_upto_here_2
436
5d2b97cd 437void
e81d98ec 438scm_remember_upto_here_1 (SCM obj SCM_UNUSED)
5d2b97cd
DH
439{
440 /* Empty. Protects a single object from garbage collection. */
441}
442
443void
e81d98ec 444scm_remember_upto_here_2 (SCM obj1 SCM_UNUSED, SCM obj2 SCM_UNUSED)
5d2b97cd
DH
445{
446 /* Empty. Protects two objects from garbage collection. */
447}
448
449void
e81d98ec 450scm_remember_upto_here (SCM obj SCM_UNUSED, ...)
5d2b97cd
DH
451{
452 /* Empty. Protects any number of objects from garbage collection. */
453}
454
c209c88e 455/*
41b0806d
GB
456 These crazy functions prevent garbage collection
457 of arguments after the first argument by
458 ensuring they remain live throughout the
459 function because they are used in the last
460 line of the code block.
461 It'd be better to have a nice compiler hint to
462 aid the conservative stack-scanning GC. --03/09/00 gjb */
0f2d19dd
JB
463SCM
464scm_return_first (SCM elt, ...)
0f2d19dd
JB
465{
466 return elt;
467}
468
41b0806d
GB
469int
470scm_return_first_int (int i, ...)
471{
472 return i;
473}
474
0f2d19dd 475
0f2d19dd 476SCM
6e8d25a6 477scm_permanent_object (SCM obj)
0f2d19dd 478{
8e7b3e98 479 return (scm_gc_protect_object (obj));
0f2d19dd
JB
480}
481
482
7bd4fbe2
MD
483/* Protect OBJ from the garbage collector. OBJ will not be freed, even if all
484 other references are dropped, until the object is unprotected by calling
6b1b030e 485 scm_gc_unprotect_object (OBJ). Calls to scm_gc_protect/unprotect_object nest,
7bd4fbe2
MD
486 i. e. it is possible to protect the same object several times, but it is
487 necessary to unprotect the object the same number of times to actually get
488 the object unprotected. It is an error to unprotect an object more often
489 than it has been protected before. The function scm_protect_object returns
490 OBJ.
491*/
492
493/* Implementation note: For every object X, there is a counter which
1f584400 494 scm_gc_protect_object (X) increments and scm_gc_unprotect_object (X) decrements.
7bd4fbe2 495*/
686765af 496
7eec4c37
HWN
497
498
ef290276 499SCM
6b1b030e 500scm_gc_protect_object (SCM obj)
ef290276 501{
686765af 502 SCM handle;
9d47a1e6 503
686765af 504 /* This critical section barrier will be replaced by a mutex. */
33b320ae
NJ
505 /* njrev: Indeed; if my comment above is correct, there is the same
506 critsec/mutex inconsistency here. */
9de87eea 507 SCM_CRITICAL_SECTION_START;
9d47a1e6 508
acbccb0c 509 handle = scm_hashq_create_handle_x (scm_protects, obj, scm_from_int (0));
e11e83f3 510 SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), scm_from_int (1)));
9d47a1e6 511
7eec4c37
HWN
512 protected_obj_count ++;
513
9de87eea 514 SCM_CRITICAL_SECTION_END;
9d47a1e6 515
ef290276
JB
516 return obj;
517}
518
519
520/* Remove any protection for OBJ established by a prior call to
dab7f566 521 scm_protect_object. This function returns OBJ.
ef290276 522
dab7f566 523 See scm_protect_object for more information. */
ef290276 524SCM
6b1b030e 525scm_gc_unprotect_object (SCM obj)
ef290276 526{
686765af 527 SCM handle;
9d47a1e6 528
686765af 529 /* This critical section barrier will be replaced by a mutex. */
33b320ae 530 /* njrev: and again. */
9de87eea 531 SCM_CRITICAL_SECTION_START;
9d47a1e6 532
0ff7e3ff
HWN
533 if (scm_gc_running_p)
534 {
535 fprintf (stderr, "scm_unprotect_object called during GC.\n");
536 abort ();
537 }
b17e0ac3 538
acbccb0c 539 handle = scm_hashq_get_handle (scm_protects, obj);
9d47a1e6 540
7888309b 541 if (scm_is_false (handle))
686765af 542 {
0f0f0899
MD
543 fprintf (stderr, "scm_unprotect_object called on unprotected object\n");
544 abort ();
686765af 545 }
6a199940
DH
546 else
547 {
e11e83f3 548 SCM count = scm_difference (SCM_CDR (handle), scm_from_int (1));
bc36d050 549 if (scm_is_eq (count, scm_from_int (0)))
acbccb0c 550 scm_hashq_remove_x (scm_protects, obj);
6a199940 551 else
1be6b49c 552 SCM_SETCDR (handle, count);
6a199940 553 }
7eec4c37 554 protected_obj_count --;
686765af 555
9de87eea 556 SCM_CRITICAL_SECTION_END;
ef290276
JB
557
558 return obj;
559}
560
6b1b030e
ML
561void
562scm_gc_register_root (SCM *p)
563{
8e7b3e98 564 /* Nothing. */
6b1b030e
ML
565}
566
567void
568scm_gc_unregister_root (SCM *p)
569{
8e7b3e98 570 /* Nothing. */
6b1b030e
ML
571}
572
573void
574scm_gc_register_roots (SCM *b, unsigned long n)
575{
576 SCM *p = b;
577 for (; p < b + n; ++p)
578 scm_gc_register_root (p);
579}
580
581void
582scm_gc_unregister_roots (SCM *b, unsigned long n)
583{
584 SCM *p = b;
585 for (; p < b + n; ++p)
586 scm_gc_unregister_root (p);
587}
588
0f2d19dd 589\f
a00c95d9 590
4c48ba06 591
c8a1bdc4
HWN
592/*
593 MOVE THIS FUNCTION. IT DOES NOT HAVE ANYTHING TODO WITH GC.
594 */
85db4a2c
DH
595
596/* Get an integer from an environment variable. */
c8a1bdc4
HWN
597int
598scm_getenv_int (const char *var, int def)
85db4a2c 599{
c8a1bdc4
HWN
600 char *end = 0;
601 char *val = getenv (var);
602 long res = def;
85db4a2c
DH
603 if (!val)
604 return def;
605 res = strtol (val, &end, 10);
606 if (end == val)
607 return def;
608 return res;
609}
610
c35738c1
MD
611void
612scm_storage_prehistory ()
613{
184327a6 614 GC_all_interior_pointers = 0;
6360beb2
AW
615 free_space_divisor = scm_getenv_int ("GC_FREE_SPACE_DIVISOR", 3);
616 minimum_free_space_divisor = free_space_divisor;
617 target_free_space_divisor = free_space_divisor;
618 GC_set_free_space_divisor (free_space_divisor);
184327a6 619
a82e7953 620 GC_INIT ();
e7bca227 621
11d2fc06
LC
622#if (! ((defined GC_VERSION_MAJOR) && (GC_VERSION_MAJOR >= 7))) \
623 && (defined SCM_I_GSC_USE_PTHREAD_THREADS)
e7bca227
LC
624 /* When using GC 6.8, this call is required to initialize thread-local
625 freelists (shouldn't be necessary with GC 7.0). */
626 GC_init ();
627#endif
628
fdab75a1 629 GC_expand_hp (SCM_DEFAULT_INIT_HEAP_SIZE_2);
915b3f9f 630
184327a6
LC
631 /* We only need to register a displacement for those types for which the
632 higher bits of the type tag are used to store a pointer (that is, a
633 pointer to an 8-octet aligned region). For `scm_tc3_struct', this is
634 handled in `scm_alloc_struct ()'. */
635 GC_REGISTER_DISPLACEMENT (scm_tc3_cons);
314b8716 636 /* GC_REGISTER_DISPLACEMENT (scm_tc3_unused); */
184327a6 637
915b3f9f 638 /* Sanity check. */
acbccb0c 639 if (!GC_is_visible (&scm_protects))
915b3f9f 640 abort ();
a82e7953 641
c35738c1
MD
642 scm_c_hook_init (&scm_before_gc_c_hook, 0, SCM_C_HOOK_NORMAL);
643 scm_c_hook_init (&scm_before_mark_c_hook, 0, SCM_C_HOOK_NORMAL);
644 scm_c_hook_init (&scm_before_sweep_c_hook, 0, SCM_C_HOOK_NORMAL);
645 scm_c_hook_init (&scm_after_sweep_c_hook, 0, SCM_C_HOOK_NORMAL);
646 scm_c_hook_init (&scm_after_gc_c_hook, 0, SCM_C_HOOK_NORMAL);
647}
85db4a2c 648
9de87eea 649scm_i_pthread_mutex_t scm_i_gc_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
eb01cb64 650
562cd1b8
AW
651void
652scm_init_gc_protect_object ()
0f2d19dd 653{
acbccb0c 654 scm_protects = scm_c_make_hash_table (31);
4a4c9785 655
9de87eea
MV
656#if 0
657 /* We can't have a cleanup handler since we have no thread to run it
658 in. */
659
a18bcd0e 660#ifdef HAVE_ATEXIT
c45acc34 661 atexit (cleanup);
e52ceaac
MD
662#else
663#ifdef HAVE_ON_EXIT
664 on_exit (cleanup, 0);
665#endif
9de87eea
MV
666#endif
667
a18bcd0e 668#endif
0f2d19dd 669}
939794ce 670
0f2d19dd
JB
671\f
672
939794ce
DH
673SCM scm_after_gc_hook;
674
cc3546b0 675static SCM after_gc_async_cell;
939794ce 676
cc3546b0
AW
677/* The function after_gc_async_thunk causes the execution of the
678 * after-gc-hook. It is run after the gc, as soon as the asynchronous
679 * events are handled by the evaluator.
939794ce
DH
680 */
681static SCM
cc3546b0 682after_gc_async_thunk (void)
939794ce 683{
cc3546b0
AW
684 /* Fun, no? Hook-run *and* run-hook? */
685 scm_c_hook_run (&scm_after_gc_c_hook, NULL);
939794ce 686 scm_c_run_hook (scm_after_gc_hook, SCM_EOL);
939794ce
DH
687 return SCM_UNSPECIFIED;
688}
689
690
cc3546b0
AW
691/* The function queue_after_gc_hook is run by the scm_before_gc_c_hook
692 * at the end of the garbage collection. The only purpose of this
693 * function is to mark the after_gc_async (which will eventually lead to
694 * the execution of the after_gc_async_thunk).
939794ce
DH
695 */
696static void *
cc3546b0
AW
697queue_after_gc_hook (void * hook_data SCM_UNUSED,
698 void *fn_data SCM_UNUSED,
699 void *data SCM_UNUSED)
e81d98ec
DH
700{
701 /* If cell access debugging is enabled, the user may choose to perform
702 * additional garbage collections after an arbitrary number of cell
703 * accesses. We don't want the scheme level after-gc-hook to be performed
704 * for each of these garbage collections for the following reason: The
705 * execution of the after-gc-hook causes cell accesses itself. Thus, if the
706 * after-gc-hook was performed with every gc, and if the gc was performed
707 * after a very small number of cell accesses, then the number of cell
708 * accesses during the execution of the after-gc-hook will suffice to cause
709 * the execution of the next gc. Then, guile would keep executing the
710 * after-gc-hook over and over again, and would never come to do other
711 * things.
eae33935 712 *
e81d98ec
DH
713 * To overcome this problem, if cell access debugging with additional
714 * garbage collections is enabled, the after-gc-hook is never run by the
715 * garbage collecter. When running guile with cell access debugging and the
716 * execution of the after-gc-hook is desired, then it is necessary to run
717 * the hook explicitly from the user code. This has the effect, that from
718 * the scheme level point of view it seems that garbage collection is
719 * performed with a much lower frequency than it actually is. Obviously,
720 * this will not work for code that depends on a fixed one to one
721 * relationship between the execution counts of the C level garbage
722 * collection hooks and the execution count of the scheme level
723 * after-gc-hook.
724 */
9de87eea 725
e81d98ec 726#if (SCM_DEBUG_CELL_ACCESSES == 1)
eab1b259 727 if (scm_debug_cells_gc_interval == 0)
e81d98ec 728#endif
cc3546b0
AW
729 {
730 scm_i_thread *t = SCM_I_CURRENT_THREAD;
731
732 if (scm_is_false (SCM_CDR (after_gc_async_cell)))
733 {
734 SCM_SETCDR (after_gc_async_cell, t->active_asyncs);
735 t->active_asyncs = after_gc_async_cell;
736 t->pending_asyncs = 1;
737 }
738 }
e81d98ec 739
939794ce
DH
740 return NULL;
741}
742
00b6ef23
AW
743\f
744
745static void *
746start_gc_timer (void * hook_data SCM_UNUSED,
747 void *fn_data SCM_UNUSED,
748 void *data SCM_UNUSED)
749{
750 if (!gc_start_time)
751 gc_start_time = scm_c_get_internal_run_time ();
752
753 return NULL;
754}
755
756static void *
757accumulate_gc_timer (void * hook_data SCM_UNUSED,
758 void *fn_data SCM_UNUSED,
759 void *data SCM_UNUSED)
760{
761 if (gc_start_time)
6360beb2
AW
762 {
763 long now = scm_c_get_internal_run_time ();
00b6ef23
AW
764 gc_time_taken += now - gc_start_time;
765 gc_start_time = 0;
766 }
767
768 return NULL;
769}
770
6360beb2
AW
771/* Return some idea of the memory footprint of a process, in bytes.
772 Currently only works on Linux systems. */
773static size_t
774get_image_size (void)
775{
776 unsigned long size, resident, share;
777 size_t ret;
778
779 FILE *fp = fopen ("/proc/self/statm", "r");
780
781 if (fp && fscanf (fp, "%lu %lu %lu", &size, &resident, &share) == 3)
782 ret = resident * 4096;
783
784 if (fp)
785 fclose (fp);
786
787 return ret;
788}
789
790/* Make GC run more frequently when the process image size is growing,
791 measured against the number of bytes allocated through the GC.
792
793 If Guile is allocating at a GC-managed heap size H, libgc will tend
794 to limit the process image size to H*N. But if at the same time the
795 user program is mallocating at a rate M bytes per GC-allocated byte,
796 then the process stabilizes at H*N*M -- assuming that collecting data
797 will result in malloc'd data being freed. It doesn't take a very
798 large M for this to be a bad situation. To limit the image size,
799 Guile should GC more often -- the bigger the M, the more often.
800
801 Numeric functions that produce bigger and bigger integers are
802 pessimal, because M is an increasing function of time. Here is an
803 example of such a function:
804
805 (define (factorial n)
806 (define (fac n acc)
807 (if (<= n 1)
808 acc
809 (fac (1- n) (* n acc))))
810 (fac n 1))
811
812 It is possible for a process to grow for reasons that will not be
813 solved by faster GC. In that case M will be estimated as
814 artificially high for a while, and so GC will happen more often on
815 the Guile side. But when it stabilizes, Guile can ease back the GC
816 frequency.
817
818 The key is to measure process image growth, not mallocation rate.
819 For maximum effectiveness, Guile reacts quickly to process growth,
820 and exponentially backs down when the process stops growing.
821
822 See http://thread.gmane.org/gmane.lisp.guile.devel/12552/focus=12936
823 for further discussion.
824 */
825static void *
826adjust_gc_frequency (void * hook_data SCM_UNUSED,
827 void *fn_data SCM_UNUSED,
828 void *data SCM_UNUSED)
829{
830 static size_t prev_image_size = 0;
831 static size_t prev_bytes_alloced = 0;
832 size_t image_size;
833 size_t bytes_alloced;
834
835 image_size = get_image_size ();
836 bytes_alloced = GC_get_total_bytes ();
837
d1c03624 838#define HEURISTICS_DEBUG 0
6360beb2
AW
839
840#if HEURISTICS_DEBUG
841 fprintf (stderr, "prev image / alloced: %lu / %lu\n", prev_image_size, prev_bytes_alloced);
842 fprintf (stderr, " image / alloced: %lu / %lu\n", image_size, bytes_alloced);
843 fprintf (stderr, "divisor %lu / %f\n", free_space_divisor, target_free_space_divisor);
844#endif
845
846 if (prev_image_size && bytes_alloced != prev_bytes_alloced)
847 {
848 double growth_rate, new_target_free_space_divisor;
849 double decay_factor = 0.5;
850 double hysteresis = 0.1;
851
852 growth_rate = ((double) image_size - prev_image_size)
853 / ((double)bytes_alloced - prev_bytes_alloced);
854
855#if HEURISTICS_DEBUG
856 fprintf (stderr, "growth rate %f\n", growth_rate);
857#endif
858
859 new_target_free_space_divisor = minimum_free_space_divisor;
860
861 if (growth_rate > 0)
862 new_target_free_space_divisor *= 1.0 + growth_rate;
863
864#if HEURISTICS_DEBUG
865 fprintf (stderr, "new divisor %f\n", new_target_free_space_divisor);
866#endif
867
868 if (new_target_free_space_divisor < target_free_space_divisor)
869 /* Decay down. */
870 target_free_space_divisor =
871 (decay_factor * target_free_space_divisor
872 + (1.0 - decay_factor) * new_target_free_space_divisor);
873 else
874 /* Jump up. */
875 target_free_space_divisor = new_target_free_space_divisor;
876
877#if HEURISTICS_DEBUG
878 fprintf (stderr, "new target divisor %f\n", target_free_space_divisor);
879#endif
880
881 if (free_space_divisor + 0.5 + hysteresis < target_free_space_divisor
882 || free_space_divisor - 0.5 - hysteresis > target_free_space_divisor)
883 {
884 free_space_divisor = lround (target_free_space_divisor);
885#if HEURISTICS_DEBUG
886 fprintf (stderr, "new divisor %lu\n", free_space_divisor);
887#endif
888 GC_set_free_space_divisor (free_space_divisor);
889 }
890 }
891
892 prev_image_size = image_size;
893 prev_bytes_alloced = bytes_alloced;
894
895 return NULL;
896}
897
00b6ef23
AW
898
899\f
900
26224b3f
LC
901char const *
902scm_i_tag_name (scm_t_bits tag)
903{
74ec8d78 904 switch (tag & 0x7f) /* 7 bits */
26224b3f
LC
905 {
906 case scm_tcs_struct:
907 return "struct";
908 case scm_tcs_cons_imcar:
909 return "cons (immediate car)";
910 case scm_tcs_cons_nimcar:
911 return "cons (non-immediate car)";
5b46a8c2 912 case scm_tc7_pointer:
e2c2a699 913 return "foreign";
c99de5aa
AW
914 case scm_tc7_hashtable:
915 return "hashtable";
9ea31741
AW
916 case scm_tc7_fluid:
917 return "fluid";
918 case scm_tc7_dynamic_state:
919 return "dynamic state";
6f3b0cc2
AW
920 case scm_tc7_frame:
921 return "frame";
922 case scm_tc7_objcode:
923 return "objcode";
924 case scm_tc7_vm:
925 return "vm";
926 case scm_tc7_vm_cont:
927 return "vm continuation";
26224b3f
LC
928 case scm_tc7_wvect:
929 return "weak vector";
930 case scm_tc7_vector:
931 return "vector";
26224b3f
LC
932 case scm_tc7_number:
933 switch (tag)
934 {
935 case scm_tc16_real:
936 return "real";
937 break;
938 case scm_tc16_big:
939 return "bignum";
940 break;
941 case scm_tc16_complex:
942 return "complex number";
943 break;
944 case scm_tc16_fraction:
945 return "fraction";
946 break;
947 }
948 break;
949 case scm_tc7_string:
950 return "string";
951 break;
952 case scm_tc7_stringbuf:
953 return "string buffer";
954 break;
955 case scm_tc7_symbol:
956 return "symbol";
957 break;
958 case scm_tc7_variable:
959 return "variable";
960 break;
26224b3f
LC
961 case scm_tc7_port:
962 return "port";
963 break;
964 case scm_tc7_smob:
74ec8d78
AW
965 {
966 int k = 0xff & (tag >> 8);
967 return (scm_smobs[k].name);
968 }
26224b3f
LC
969 break;
970 }
971
972 return NULL;
973}
974
975
26224b3f
LC
976
977\f
0f2d19dd
JB
978void
979scm_init_gc ()
0f2d19dd 980{
a82e7953 981 /* `GC_INIT ()' was invoked in `scm_storage_prehistory ()'. */
d678e25c 982
f39448c5 983 scm_after_gc_hook = scm_make_hook (SCM_INUM0);
fde50407 984 scm_c_define ("after-gc-hook", scm_after_gc_hook);
939794ce 985
cc3546b0
AW
986 /* When the async is to run, the cdr of the gc_async pair gets set to
987 the asyncs queue of the current thread. */
988 after_gc_async_cell = scm_cons (scm_c_make_gsubr ("%after-gc-thunk", 0, 0, 0,
989 after_gc_async_thunk),
990 SCM_BOOL_F);
939794ce 991
cc3546b0 992 scm_c_hook_add (&scm_before_gc_c_hook, queue_after_gc_hook, NULL, 0);
00b6ef23
AW
993 scm_c_hook_add (&scm_before_gc_c_hook, start_gc_timer, NULL, 0);
994 scm_c_hook_add (&scm_after_gc_c_hook, accumulate_gc_timer, NULL, 0);
6360beb2 995 scm_c_hook_add (&scm_after_gc_c_hook, adjust_gc_frequency, NULL, 0);
66b229d5
AW
996
997#ifdef HAVE_GC_SET_START_CALLBACK
cc3546b0 998 GC_set_start_callback (run_before_gc_c_hook);
66b229d5 999#endif
939794ce 1000
a0599745 1001#include "libguile/gc.x"
0f2d19dd 1002}
89e00824 1003
c8a1bdc4
HWN
1004
1005void
1006scm_gc_sweep (void)
1007#define FUNC_NAME "scm_gc_sweep"
1008{
26224b3f 1009 /* FIXME */
cd169c5a 1010 fprintf (stderr, "%s: doing nothing\n", FUNC_NAME);
c8a1bdc4 1011}
c8a1bdc4
HWN
1012#undef FUNC_NAME
1013
89e00824
ML
1014/*
1015 Local Variables:
1016 c-file-style: "gnu"
1017 End:
1018*/