remove scm_tc7_gsubr
[bpt/guile.git] / libguile / gc.c
1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2003, 2006, 2008, 2009, 2010 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 #include "libguile/gen-scmconfig.h"
26
27 #include <stdio.h>
28 #include <errno.h>
29 #include <string.h>
30
31 #ifdef __ia64__
32 #include <ucontext.h>
33 extern unsigned long * __libc_ia64_register_backing_store_base;
34 #endif
35
36 #include "libguile/_scm.h"
37 #include "libguile/eval.h"
38 #include "libguile/stime.h"
39 #include "libguile/stackchk.h"
40 #include "libguile/struct.h"
41 #include "libguile/smob.h"
42 #include "libguile/arrays.h"
43 #include "libguile/async.h"
44 #include "libguile/ports.h"
45 #include "libguile/root.h"
46 #include "libguile/strings.h"
47 #include "libguile/vectors.h"
48 #include "libguile/weaks.h"
49 #include "libguile/hashtab.h"
50 #include "libguile/tags.h"
51
52 #include "libguile/private-gc.h"
53 #include "libguile/validate.h"
54 #include "libguile/deprecation.h"
55 #include "libguile/gc.h"
56 #include "libguile/dynwind.h"
57
58 #include "libguile/bdw-gc.h"
59
60 #ifdef GUILE_DEBUG_MALLOC
61 #include "libguile/debug-malloc.h"
62 #endif
63
64 #ifdef HAVE_MALLOC_H
65 #include <malloc.h>
66 #endif
67
68 #ifdef HAVE_UNISTD_H
69 #include <unistd.h>
70 #endif
71
72 /* Lock this mutex before doing lazy sweeping.
73 */
74 scm_i_pthread_mutex_t scm_i_sweep_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
75
76 /* Set this to != 0 if every cell that is accessed shall be checked:
77 */
78 int scm_debug_cell_accesses_p = 0;
79 int scm_expensive_debug_cell_accesses_p = 0;
80
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 */
84 int scm_debug_cells_gc_interval = 0;
85
86 /*
87 Global variable, so you can switch it off at runtime by setting
88 scm_i_cell_validation_already_running.
89 */
90 int scm_i_cell_validation_already_running ;
91
92 static SCM protects;
93
94
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 */
109 void
110 scm_i_expensive_validation_check (SCM cell)
111 {
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;
118
119 if (counter != 0)
120 {
121 --counter;
122 }
123 else
124 {
125 counter = scm_debug_cells_gc_interval;
126 scm_gc ();
127 }
128 }
129 }
130
131 void
132 scm_assert_cell_valid (SCM cell)
133 {
134 if (!scm_i_cell_validation_already_running && scm_debug_cell_accesses_p)
135 {
136 scm_i_cell_validation_already_running = 1; /* set to avoid recursion */
137
138 /*
139 During GC, no user-code should be run, and the guile core
140 should use non-protected accessors.
141 */
142 if (scm_gc_running_p)
143 return;
144
145 /*
146 Only scm_in_heap_p and rescanning the heap is wildly
147 expensive.
148 */
149 if (scm_expensive_debug_cell_accesses_p)
150 scm_i_expensive_validation_check (cell);
151
152 scm_i_cell_validation_already_running = 0; /* re-enable */
153 }
154 }
155
156
157
158 SCM_DEFINE (scm_set_debug_cell_accesses_x, "set-debug-cell-accesses!", 1, 0, 0,
159 (SCM flag),
160 "If @var{flag} is @code{#f}, cell access checking is disabled.\n"
161 "If @var{flag} is @code{#t}, cheap cell access checking is enabled,\n"
162 "but no additional calls to garbage collection are issued.\n"
163 "If @var{flag} is a number, strict cell access checking is enabled,\n"
164 "with an additional garbage collection after the given\n"
165 "number of cell accesses.\n"
166 "This procedure only exists when the compile-time flag\n"
167 "@code{SCM_DEBUG_CELL_ACCESSES} was set to 1.")
168 #define FUNC_NAME s_scm_set_debug_cell_accesses_x
169 {
170 if (scm_is_false (flag))
171 {
172 scm_debug_cell_accesses_p = 0;
173 }
174 else if (scm_is_eq (flag, SCM_BOOL_T))
175 {
176 scm_debug_cells_gc_interval = 0;
177 scm_debug_cell_accesses_p = 1;
178 scm_expensive_debug_cell_accesses_p = 0;
179 }
180 else
181 {
182 scm_debug_cells_gc_interval = scm_to_signed_integer (flag, 0, INT_MAX);
183 scm_debug_cell_accesses_p = 1;
184 scm_expensive_debug_cell_accesses_p = 1;
185 }
186 return SCM_UNSPECIFIED;
187 }
188 #undef FUNC_NAME
189
190
191 #endif /* SCM_DEBUG_CELL_ACCESSES == 1 */
192
193 \f
194 /* Hooks. */
195 scm_t_c_hook scm_before_gc_c_hook;
196 scm_t_c_hook scm_before_mark_c_hook;
197 scm_t_c_hook scm_before_sweep_c_hook;
198 scm_t_c_hook scm_after_sweep_c_hook;
199 scm_t_c_hook scm_after_gc_c_hook;
200
201
202 /* GC Statistics Keeping
203 */
204 unsigned long scm_gc_ports_collected = 0;
205
206 static unsigned long protected_obj_count = 0;
207
208
209 SCM_SYMBOL (sym_cells_allocated, "cells-allocated");
210 SCM_SYMBOL (sym_heap_size, "heap-size");
211 SCM_SYMBOL (sym_heap_free_size, "heap-free-size");
212 SCM_SYMBOL (sym_heap_total_allocated, "heap-total-allocated");
213 SCM_SYMBOL (sym_mallocated, "bytes-malloced");
214 SCM_SYMBOL (sym_mtrigger, "gc-malloc-threshold");
215 SCM_SYMBOL (sym_heap_segments, "cell-heap-segments");
216 SCM_SYMBOL (sym_gc_time_taken, "gc-time-taken");
217 SCM_SYMBOL (sym_gc_mark_time_taken, "gc-mark-time-taken");
218 SCM_SYMBOL (sym_times, "gc-times");
219 SCM_SYMBOL (sym_cells_marked, "cells-marked");
220 SCM_SYMBOL (sym_cells_marked_conservatively, "cells-marked-conservatively");
221 SCM_SYMBOL (sym_cells_swept, "cells-swept");
222 SCM_SYMBOL (sym_malloc_yield, "malloc-yield");
223 SCM_SYMBOL (sym_cell_yield, "cell-yield");
224 SCM_SYMBOL (sym_protected_objects, "protected-objects");
225 SCM_SYMBOL (sym_total_cells_allocated, "total-cells-allocated");
226
227
228 /* Number of calls to SCM_NEWCELL since startup. */
229 unsigned scm_newcell_count;
230 unsigned scm_newcell2_count;
231
232
233 /* {Scheme Interface to GC}
234 */
235 static SCM
236 tag_table_to_type_alist (void *closure, SCM key, SCM val, SCM acc)
237 {
238 if (scm_is_integer (key))
239 {
240 int c_tag = scm_to_int (key);
241
242 char const * name = scm_i_tag_name (c_tag);
243 if (name != NULL)
244 {
245 key = scm_from_locale_string (name);
246 }
247 else
248 {
249 char s[100];
250 sprintf (s, "tag %d", c_tag);
251 key = scm_from_locale_string (s);
252 }
253 }
254
255 return scm_cons (scm_cons (key, val), acc);
256 }
257
258 SCM_DEFINE (scm_gc_live_object_stats, "gc-live-object-stats", 0, 0, 0,
259 (),
260 "Return an alist of statistics of the current live objects. ")
261 #define FUNC_NAME s_scm_gc_live_object_stats
262 {
263 SCM tab = scm_make_hash_table (scm_from_int (57));
264 SCM alist;
265
266 alist
267 = scm_internal_hash_fold (&tag_table_to_type_alist, NULL, SCM_EOL, tab);
268
269 return alist;
270 }
271 #undef FUNC_NAME
272
273 extern int scm_gc_malloc_yield_percentage;
274 SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
275 (),
276 "Return an association list of statistics about Guile's current\n"
277 "use of storage.\n")
278 #define FUNC_NAME s_scm_gc_stats
279 {
280 SCM answer;
281 size_t heap_size, free_bytes, bytes_since_gc, total_bytes;
282 size_t gc_times;
283
284 heap_size = GC_get_heap_size ();
285 free_bytes = GC_get_free_bytes ();
286 bytes_since_gc = GC_get_bytes_since_gc ();
287 total_bytes = GC_get_total_bytes ();
288 gc_times = GC_gc_no;
289
290 /* njrev: can any of these scm_cons's or scm_list_n signal a memory
291 error? If so we need a frame here. */
292 answer =
293 scm_list_n (scm_cons (sym_gc_time_taken, SCM_INUM0),
294 #if 0
295 scm_cons (sym_cells_allocated,
296 scm_from_ulong (local_scm_cells_allocated)),
297 scm_cons (sym_mallocated,
298 scm_from_ulong (local_scm_mallocated)),
299 scm_cons (sym_mtrigger,
300 scm_from_ulong (local_scm_mtrigger)),
301 scm_cons (sym_gc_mark_time_taken,
302 scm_from_ulong (local_scm_gc_mark_time_taken)),
303 scm_cons (sym_cells_marked,
304 scm_from_double (local_scm_gc_cells_marked)),
305 scm_cons (sym_cells_swept,
306 scm_from_double (local_scm_gc_cells_swept)),
307 scm_cons (sym_malloc_yield,
308 scm_from_long (local_scm_gc_malloc_yield_percentage)),
309 scm_cons (sym_cell_yield,
310 scm_from_long (local_scm_gc_cell_yield_percentage)),
311 scm_cons (sym_heap_segments, heap_segs),
312 #endif
313 scm_cons (sym_heap_size, scm_from_size_t (heap_size)),
314 scm_cons (sym_heap_free_size, scm_from_size_t (free_bytes)),
315 scm_cons (sym_heap_total_allocated,
316 scm_from_size_t (total_bytes)),
317 scm_cons (sym_protected_objects,
318 scm_from_ulong (protected_obj_count)),
319 scm_cons (sym_times, scm_from_size_t (gc_times)),
320 SCM_UNDEFINED);
321
322 return answer;
323 }
324 #undef FUNC_NAME
325
326
327 SCM_DEFINE (scm_gc_dump, "gc-dump", 0, 0, 0,
328 (void),
329 "Dump information about the garbage collector's internal data "
330 "structures and memory usage to the standard output.")
331 #define FUNC_NAME s_scm_gc_dump
332 {
333 GC_dump ();
334
335 return SCM_UNSPECIFIED;
336 }
337 #undef FUNC_NAME
338
339
340 SCM_DEFINE (scm_object_address, "object-address", 1, 0, 0,
341 (SCM obj),
342 "Return an integer that for the lifetime of @var{obj} is uniquely\n"
343 "returned by this function for @var{obj}")
344 #define FUNC_NAME s_scm_object_address
345 {
346 return scm_from_ulong (SCM_UNPACK (obj));
347 }
348 #undef FUNC_NAME
349
350
351 SCM_DEFINE (scm_gc_disable, "gc-disable", 0, 0, 0,
352 (),
353 "Disables the garbage collector. Nested calls are permitted. "
354 "GC is re-enabled once @code{gc-enable} has been called the "
355 "same number of times @code{gc-disable} was called.")
356 #define FUNC_NAME s_scm_gc_disable
357 {
358 GC_disable ();
359 return SCM_UNSPECIFIED;
360 }
361 #undef FUNC_NAME
362
363 SCM_DEFINE (scm_gc_enable, "gc-enable", 0, 0, 0,
364 (),
365 "Enables the garbage collector.")
366 #define FUNC_NAME s_scm_gc_enable
367 {
368 GC_enable ();
369 return SCM_UNSPECIFIED;
370 }
371 #undef FUNC_NAME
372
373
374 SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
375 (),
376 "Scans all of SCM objects and reclaims for further use those that are\n"
377 "no longer accessible.")
378 #define FUNC_NAME s_scm_gc
379 {
380 scm_i_scm_pthread_mutex_lock (&scm_i_sweep_mutex);
381 scm_i_gc ("call");
382 /* njrev: It looks as though other places, e.g. scm_realloc,
383 can call scm_i_gc without acquiring the sweep mutex. Does this
384 matter? Also scm_i_gc (or its descendants) touch the
385 scm_sys_protects, which are protected in some cases
386 (e.g. scm_permobjs above in scm_gc_stats) by a critical section,
387 not by the sweep mutex. Shouldn't all the GC-relevant objects be
388 protected in the same way? */
389 scm_i_pthread_mutex_unlock (&scm_i_sweep_mutex);
390 scm_c_hook_run (&scm_after_gc_c_hook, 0);
391 return SCM_UNSPECIFIED;
392 }
393 #undef FUNC_NAME
394
395 void
396 scm_i_gc (const char *what)
397 {
398 GC_gcollect ();
399 }
400
401
402 \f
403 /* {GC Protection Helper Functions}
404 */
405
406
407 /*
408 * If within a function you need to protect one or more scheme objects from
409 * garbage collection, pass them as parameters to one of the
410 * scm_remember_upto_here* functions below. These functions don't do
411 * anything, but since the compiler does not know that they are actually
412 * no-ops, it will generate code that calls these functions with the given
413 * parameters. Therefore, you can be sure that the compiler will keep those
414 * scheme values alive (on the stack or in a register) up to the point where
415 * scm_remember_upto_here* is called. In other words, place the call to
416 * scm_remember_upto_here* _behind_ the last code in your function, that
417 * depends on the scheme object to exist.
418 *
419 * Example: We want to make sure that the string object str does not get
420 * garbage collected during the execution of 'some_function' in the code
421 * below, because otherwise the characters belonging to str would be freed and
422 * 'some_function' might access freed memory. To make sure that the compiler
423 * keeps str alive on the stack or in a register such that it is visible to
424 * the conservative gc we add the call to scm_remember_upto_here_1 _after_ the
425 * call to 'some_function'. Note that this would not be necessary if str was
426 * used anyway after the call to 'some_function'.
427 * char *chars = scm_i_string_chars (str);
428 * some_function (chars);
429 * scm_remember_upto_here_1 (str); // str will be alive up to this point.
430 */
431
432 /* Remove any macro versions of these while defining the functions.
433 Functions are always included in the library, for upward binary
434 compatibility and in case combinations of GCC and non-GCC are used. */
435 #undef scm_remember_upto_here_1
436 #undef scm_remember_upto_here_2
437
438 void
439 scm_remember_upto_here_1 (SCM obj SCM_UNUSED)
440 {
441 /* Empty. Protects a single object from garbage collection. */
442 }
443
444 void
445 scm_remember_upto_here_2 (SCM obj1 SCM_UNUSED, SCM obj2 SCM_UNUSED)
446 {
447 /* Empty. Protects two objects from garbage collection. */
448 }
449
450 void
451 scm_remember_upto_here (SCM obj SCM_UNUSED, ...)
452 {
453 /* Empty. Protects any number of objects from garbage collection. */
454 }
455
456 /*
457 These crazy functions prevent garbage collection
458 of arguments after the first argument by
459 ensuring they remain live throughout the
460 function because they are used in the last
461 line of the code block.
462 It'd be better to have a nice compiler hint to
463 aid the conservative stack-scanning GC. --03/09/00 gjb */
464 SCM
465 scm_return_first (SCM elt, ...)
466 {
467 return elt;
468 }
469
470 int
471 scm_return_first_int (int i, ...)
472 {
473 return i;
474 }
475
476
477 SCM
478 scm_permanent_object (SCM obj)
479 {
480 return (scm_gc_protect_object (obj));
481 }
482
483
484 /* Protect OBJ from the garbage collector. OBJ will not be freed, even if all
485 other references are dropped, until the object is unprotected by calling
486 scm_gc_unprotect_object (OBJ). Calls to scm_gc_protect/unprotect_object nest,
487 i. e. it is possible to protect the same object several times, but it is
488 necessary to unprotect the object the same number of times to actually get
489 the object unprotected. It is an error to unprotect an object more often
490 than it has been protected before. The function scm_protect_object returns
491 OBJ.
492 */
493
494 /* Implementation note: For every object X, there is a counter which
495 scm_gc_protect_object (X) increments and scm_gc_unprotect_object (X) decrements.
496 */
497
498
499
500 SCM
501 scm_gc_protect_object (SCM obj)
502 {
503 SCM handle;
504
505 /* This critical section barrier will be replaced by a mutex. */
506 /* njrev: Indeed; if my comment above is correct, there is the same
507 critsec/mutex inconsistency here. */
508 SCM_CRITICAL_SECTION_START;
509
510 handle = scm_hashq_create_handle_x (protects, obj, scm_from_int (0));
511 SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), scm_from_int (1)));
512
513 protected_obj_count ++;
514
515 SCM_CRITICAL_SECTION_END;
516
517 return obj;
518 }
519
520
521 /* Remove any protection for OBJ established by a prior call to
522 scm_protect_object. This function returns OBJ.
523
524 See scm_protect_object for more information. */
525 SCM
526 scm_gc_unprotect_object (SCM obj)
527 {
528 SCM handle;
529
530 /* This critical section barrier will be replaced by a mutex. */
531 /* njrev: and again. */
532 SCM_CRITICAL_SECTION_START;
533
534 if (scm_gc_running_p)
535 {
536 fprintf (stderr, "scm_unprotect_object called during GC.\n");
537 abort ();
538 }
539
540 handle = scm_hashq_get_handle (protects, obj);
541
542 if (scm_is_false (handle))
543 {
544 fprintf (stderr, "scm_unprotect_object called on unprotected object\n");
545 abort ();
546 }
547 else
548 {
549 SCM count = scm_difference (SCM_CDR (handle), scm_from_int (1));
550 if (scm_is_eq (count, scm_from_int (0)))
551 scm_hashq_remove_x (protects, obj);
552 else
553 SCM_SETCDR (handle, count);
554 }
555 protected_obj_count --;
556
557 SCM_CRITICAL_SECTION_END;
558
559 return obj;
560 }
561
562 void
563 scm_gc_register_root (SCM *p)
564 {
565 /* Nothing. */
566 }
567
568 void
569 scm_gc_unregister_root (SCM *p)
570 {
571 /* Nothing. */
572 }
573
574 void
575 scm_gc_register_roots (SCM *b, unsigned long n)
576 {
577 SCM *p = b;
578 for (; p < b + n; ++p)
579 scm_gc_register_root (p);
580 }
581
582 void
583 scm_gc_unregister_roots (SCM *b, unsigned long n)
584 {
585 SCM *p = b;
586 for (; p < b + n; ++p)
587 scm_gc_unregister_root (p);
588 }
589
590 int scm_i_terminating;
591
592 \f
593
594
595 /*
596 MOVE THIS FUNCTION. IT DOES NOT HAVE ANYTHING TODO WITH GC.
597 */
598
599 /* Get an integer from an environment variable. */
600 int
601 scm_getenv_int (const char *var, int def)
602 {
603 char *end = 0;
604 char *val = getenv (var);
605 long res = def;
606 if (!val)
607 return def;
608 res = strtol (val, &end, 10);
609 if (end == val)
610 return def;
611 return res;
612 }
613
614 void
615 scm_storage_prehistory ()
616 {
617 GC_all_interior_pointers = 0;
618 GC_set_free_space_divisor (scm_getenv_int ("GC_FREE_SPACE_DIVISOR", 3));
619
620 GC_INIT ();
621
622 #if (! ((defined GC_VERSION_MAJOR) && (GC_VERSION_MAJOR >= 7))) \
623 && (defined SCM_I_GSC_USE_PTHREAD_THREADS)
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
629 GC_expand_hp (SCM_DEFAULT_INIT_HEAP_SIZE_2);
630
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);
636 /* GC_REGISTER_DISPLACEMENT (scm_tc3_unused); */
637
638 /* Sanity check. */
639 if (!GC_is_visible (&protects))
640 abort ();
641
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 }
648
649 scm_i_pthread_mutex_t scm_i_gc_admin_mutex = SCM_I_PTHREAD_MUTEX_INITIALIZER;
650
651 void
652 scm_init_gc_protect_object ()
653 {
654 protects = scm_c_make_hash_table (31);
655
656 #if 0
657 /* We can't have a cleanup handler since we have no thread to run it
658 in. */
659
660 #ifdef HAVE_ATEXIT
661 atexit (cleanup);
662 #else
663 #ifdef HAVE_ON_EXIT
664 on_exit (cleanup, 0);
665 #endif
666 #endif
667
668 #endif
669 }
670
671 \f
672
673 SCM scm_after_gc_hook;
674
675 static SCM gc_async;
676
677 /* The function gc_async_thunk causes the execution of the after-gc-hook. It
678 * is run after the gc, as soon as the asynchronous events are handled by the
679 * evaluator.
680 */
681 static SCM
682 gc_async_thunk (void)
683 {
684 scm_c_run_hook (scm_after_gc_hook, SCM_EOL);
685 return SCM_UNSPECIFIED;
686 }
687
688
689 /* The function mark_gc_async is run by the scm_after_gc_c_hook at the end of
690 * the garbage collection. The only purpose of this function is to mark the
691 * gc_async (which will eventually lead to the execution of the
692 * gc_async_thunk).
693 */
694 static void *
695 mark_gc_async (void * hook_data SCM_UNUSED,
696 void *fn_data SCM_UNUSED,
697 void *data SCM_UNUSED)
698 {
699 /* If cell access debugging is enabled, the user may choose to perform
700 * additional garbage collections after an arbitrary number of cell
701 * accesses. We don't want the scheme level after-gc-hook to be performed
702 * for each of these garbage collections for the following reason: The
703 * execution of the after-gc-hook causes cell accesses itself. Thus, if the
704 * after-gc-hook was performed with every gc, and if the gc was performed
705 * after a very small number of cell accesses, then the number of cell
706 * accesses during the execution of the after-gc-hook will suffice to cause
707 * the execution of the next gc. Then, guile would keep executing the
708 * after-gc-hook over and over again, and would never come to do other
709 * things.
710 *
711 * To overcome this problem, if cell access debugging with additional
712 * garbage collections is enabled, the after-gc-hook is never run by the
713 * garbage collecter. When running guile with cell access debugging and the
714 * execution of the after-gc-hook is desired, then it is necessary to run
715 * the hook explicitly from the user code. This has the effect, that from
716 * the scheme level point of view it seems that garbage collection is
717 * performed with a much lower frequency than it actually is. Obviously,
718 * this will not work for code that depends on a fixed one to one
719 * relationship between the execution counts of the C level garbage
720 * collection hooks and the execution count of the scheme level
721 * after-gc-hook.
722 */
723
724 #if (SCM_DEBUG_CELL_ACCESSES == 1)
725 if (scm_debug_cells_gc_interval == 0)
726 scm_system_async_mark (gc_async);
727 #else
728 scm_system_async_mark (gc_async);
729 #endif
730
731 return NULL;
732 }
733
734 char const *
735 scm_i_tag_name (scm_t_bits tag)
736 {
737 if (tag >= 255)
738 {
739 int k = 0xff & (tag >> 8);
740 return (scm_smobs[k].name);
741 }
742
743 switch (tag) /* 7 bits */
744 {
745 case scm_tcs_struct:
746 return "struct";
747 case scm_tcs_cons_imcar:
748 return "cons (immediate car)";
749 case scm_tcs_cons_nimcar:
750 return "cons (non-immediate car)";
751 case scm_tc7_foreign:
752 return "foreign";
753 case scm_tc7_hashtable:
754 return "hashtable";
755 case scm_tc7_fluid:
756 return "fluid";
757 case scm_tc7_dynamic_state:
758 return "dynamic state";
759 case scm_tc7_frame:
760 return "frame";
761 case scm_tc7_objcode:
762 return "objcode";
763 case scm_tc7_vm:
764 return "vm";
765 case scm_tc7_vm_cont:
766 return "vm continuation";
767 case scm_tc7_wvect:
768 return "weak vector";
769 case scm_tc7_vector:
770 return "vector";
771 case scm_tc7_number:
772 switch (tag)
773 {
774 case scm_tc16_real:
775 return "real";
776 break;
777 case scm_tc16_big:
778 return "bignum";
779 break;
780 case scm_tc16_complex:
781 return "complex number";
782 break;
783 case scm_tc16_fraction:
784 return "fraction";
785 break;
786 }
787 break;
788 case scm_tc7_string:
789 return "string";
790 break;
791 case scm_tc7_stringbuf:
792 return "string buffer";
793 break;
794 case scm_tc7_symbol:
795 return "symbol";
796 break;
797 case scm_tc7_variable:
798 return "variable";
799 break;
800 case scm_tc7_port:
801 return "port";
802 break;
803 case scm_tc7_smob:
804 return "smob"; /* should not occur. */
805 break;
806 }
807
808 return NULL;
809 }
810
811
812
813 \f
814 void
815 scm_init_gc ()
816 {
817 /* `GC_INIT ()' was invoked in `scm_storage_prehistory ()'. */
818
819 scm_after_gc_hook = scm_make_hook (SCM_INUM0);
820 scm_c_define ("after-gc-hook", scm_after_gc_hook);
821
822 gc_async = scm_c_make_gsubr ("%gc-thunk", 0, 0, 0, gc_async_thunk);
823
824 scm_c_hook_add (&scm_after_gc_c_hook, mark_gc_async, NULL, 0);
825
826 #include "libguile/gc.x"
827 }
828
829
830 void
831 scm_gc_sweep (void)
832 #define FUNC_NAME "scm_gc_sweep"
833 {
834 /* FIXME */
835 fprintf (stderr, "%s: doing nothing\n", FUNC_NAME);
836 }
837 #undef FUNC_NAME
838
839 /*
840 Local Variables:
841 c-file-style: "gnu"
842 End:
843 */