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