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