* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
[bpt/guile.git] / libguile / gc.c
CommitLineData
c709de7f 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002 Free Software Foundation, Inc.
a00c95d9 2 *
0f2d19dd
JB
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
a00c95d9 7 *
0f2d19dd
JB
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
a00c95d9 12 *
0f2d19dd
JB
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
1bbd0b84 41
1bbd0b84 42
37ddcaf6
MD
43/* #define DEBUGINFO */
44
56495472 45
0f2d19dd 46#include <stdio.h>
e6e2e95a 47#include <errno.h>
783e7774 48#include <string.h>
c8a1bdc4 49#include <assert.h>
e6e2e95a 50
d9189652
RB
51#ifdef __ia64__
52#include <ucontext.h>
bb1180ef 53extern unsigned long * __libc_ia64_register_backing_store_base;
d9189652
RB
54#endif
55
a0599745 56#include "libguile/_scm.h"
0a7a7445 57#include "libguile/eval.h"
a0599745
MD
58#include "libguile/stime.h"
59#include "libguile/stackchk.h"
60#include "libguile/struct.h"
a0599745
MD
61#include "libguile/smob.h"
62#include "libguile/unif.h"
63#include "libguile/async.h"
64#include "libguile/ports.h"
65#include "libguile/root.h"
66#include "libguile/strings.h"
67#include "libguile/vectors.h"
801cb5e7 68#include "libguile/weaks.h"
686765af 69#include "libguile/hashtab.h"
ecf470a2 70#include "libguile/tags.h"
a0599745 71
c8a1bdc4 72#include "libguile/private-gc.h"
a0599745 73#include "libguile/validate.h"
1be6b49c 74#include "libguile/deprecation.h"
a0599745 75#include "libguile/gc.h"
fce59c93 76
bc9d9bb2 77#ifdef GUILE_DEBUG_MALLOC
a0599745 78#include "libguile/debug-malloc.h"
bc9d9bb2
MD
79#endif
80
0f2d19dd 81#ifdef HAVE_MALLOC_H
95b88819 82#include <malloc.h>
0f2d19dd
JB
83#endif
84
85#ifdef HAVE_UNISTD_H
95b88819 86#include <unistd.h>
0f2d19dd
JB
87#endif
88
406c7d90 89
8c494e99 90
406c7d90
DH
91unsigned int scm_gc_running_p = 0;
92
eae33935 93/* Set this to != 0 if every cell that is accessed shall be checked:
61045190 94 */
eab1b259
HWN
95int scm_debug_cell_accesses_p = 0;
96int scm_expensive_debug_cell_accesses_p = 0;
406c7d90 97
e81d98ec
DH
98/* Set this to 0 if no additional gc's shall be performed, otherwise set it to
99 * the number of cell accesses after which a gc shall be called.
100 */
eab1b259 101int scm_debug_cells_gc_interval = 0;
e81d98ec 102
eab1b259
HWN
103/*
104 Global variable, so you can switch it off at runtime by setting
105 scm_i_cell_validation_already_running.
406c7d90 106 */
eab1b259
HWN
107int scm_i_cell_validation_already_running ;
108
109#if (SCM_DEBUG_CELL_ACCESSES == 1)
110
111
112/*
113
114 Assert that the given object is a valid reference to a valid cell. This
115 test involves to determine whether the object is a cell pointer, whether
116 this pointer actually points into a heap segment and whether the cell
117 pointed to is not a free cell. Further, additional garbage collections may
118 get executed after a user defined number of cell accesses. This helps to
119 find places in the C code where references are dropped for extremely short
120 periods.
121
122*/
406c7d90 123void
eab1b259 124scm_i_expensive_validation_check (SCM cell)
406c7d90 125{
eab1b259
HWN
126 if (!scm_in_heap_p (cell))
127 {
128 fprintf (stderr, "scm_assert_cell_valid: this object does not live in the heap: %lux\n",
129 (unsigned long) SCM_UNPACK (cell));
130 abort ();
131 }
132
133 /* If desired, perform additional garbage collections after a user
134 * defined number of cell accesses.
135 */
136 if (scm_debug_cells_gc_interval)
137 {
138 static unsigned int counter = 0;
61045190 139
eab1b259
HWN
140 if (counter != 0)
141 {
142 --counter;
143 }
144 else
145 {
146 counter = scm_debug_cells_gc_interval;
9bc4701c 147 scm_i_thread_put_to_sleep ();
eab1b259 148 scm_igc ("scm_assert_cell_valid");
9bc4701c 149 scm_i_thread_wake_up ();
eab1b259
HWN
150 }
151 }
152}
153
154void
155scm_assert_cell_valid (SCM cell)
156{
157 if (!scm_i_cell_validation_already_running && scm_debug_cell_accesses_p)
406c7d90 158 {
eab1b259 159 scm_i_cell_validation_already_running = 1; /* set to avoid recursion */
406c7d90 160
c8a1bdc4 161 /*
eab1b259
HWN
162 During GC, no user-code should be run, and the guile core
163 should use non-protected accessors.
164 */
c8a1bdc4 165 if (scm_gc_running_p)
eab1b259 166 return;
c8a1bdc4
HWN
167
168 /*
eab1b259
HWN
169 Only scm_in_heap_p and rescanning the heap is wildly
170 expensive.
171 */
172 if (scm_expensive_debug_cell_accesses_p)
173 scm_i_expensive_validation_check (cell);
c8a1bdc4
HWN
174
175 if (!SCM_GC_MARK_P (cell))
406c7d90 176 {
c8a1bdc4
HWN
177 fprintf (stderr,
178 "scm_assert_cell_valid: this object is unmarked. \n"
179 "It has been garbage-collected in the last GC run: "
180 "%lux\n",
1be6b49c 181 (unsigned long) SCM_UNPACK (cell));
406c7d90
DH
182 abort ();
183 }
c8a1bdc4 184
eab1b259 185 scm_i_cell_validation_already_running = 0; /* re-enable */
406c7d90
DH
186 }
187}
188
189
eab1b259 190
406c7d90
DH
191SCM_DEFINE (scm_set_debug_cell_accesses_x, "set-debug-cell-accesses!", 1, 0, 0,
192 (SCM flag),
1e6808ea 193 "If @var{flag} is @code{#f}, cell access checking is disabled.\n"
eab1b259 194 "If @var{flag} is @code{#t}, cheap cell access checking is enabled,\n"
e81d98ec 195 "but no additional calls to garbage collection are issued.\n"
eab1b259 196 "If @var{flag} is a number, strict cell access checking is enabled,\n"
e81d98ec
DH
197 "with an additional garbage collection after the given\n"
198 "number of cell accesses.\n"
1e6808ea
MG
199 "This procedure only exists when the compile-time flag\n"
200 "@code{SCM_DEBUG_CELL_ACCESSES} was set to 1.")
406c7d90
DH
201#define FUNC_NAME s_scm_set_debug_cell_accesses_x
202{
eab1b259
HWN
203 if (SCM_FALSEP (flag))
204 {
205 scm_debug_cell_accesses_p = 0;
206 }
207 else if (SCM_EQ_P (flag, SCM_BOOL_T))
208 {
209 scm_debug_cells_gc_interval = 0;
210 scm_debug_cell_accesses_p = 1;
211 scm_expensive_debug_cell_accesses_p = 0;
212 }
213 else if (SCM_INUMP (flag))
214 {
215 long int f = SCM_INUM (flag);
216 if (f <= 0)
217 SCM_OUT_OF_RANGE (1, flag);
218 scm_debug_cells_gc_interval = f;
219 scm_debug_cell_accesses_p = 1;
220 scm_expensive_debug_cell_accesses_p = 1;
221 }
222 else
223 {
224 SCM_WRONG_TYPE_ARG (1, flag);
225 }
406c7d90
DH
226 return SCM_UNSPECIFIED;
227}
228#undef FUNC_NAME
c8a1bdc4 229#else
0f2d19dd 230
8fef55a8 231/*
c8a1bdc4
HWN
232 Provide a stub, so people can use their Scheme code on non-debug
233 versions of GUILE as well.
4c48ba06 234 */
c8a1bdc4
HWN
235SCM_DEFINE (scm_set_debug_cell_accesses_x, "set-debug-cell-accesses!", 1, 0, 0,
236 (SCM flag),
237 "This function is used to turn on checking for a debug version of GUILE. This version does not support this functionality\n")
238#define FUNC_NAME s_scm_set_debug_cell_accesses_x
239{
240
241 /*
242 do nothing
243 */
1e71eafb 244 fprintf (stderr, "\nWARNING: GUILE was not compiled with SCM_DEBUG_CELL_ACCESSES");
c8a1bdc4
HWN
245 scm_remember_upto_here (flag);
246 return SCM_UNSPECIFIED;
247}
248#undef FUNC_NAME
ecf470a2 249
c8a1bdc4 250#endif /* SCM_DEBUG_CELL_ACCESSES == 1 */
0f2d19dd
JB
251
252\f
945fec60 253
9bc4701c
MD
254scm_t_key scm_i_freelist;
255scm_t_key scm_i_freelist2;
c8a1bdc4 256
0f2d19dd
JB
257
258/* scm_mtrigger
539b08a4 259 * is the number of bytes of malloc allocation needed to trigger gc.
0f2d19dd 260 */
c014a02e 261unsigned long scm_mtrigger;
0f2d19dd 262
0f2d19dd
JB
263/* scm_gc_heap_lock
264 * If set, don't expand the heap. Set only during gc, during which no allocation
265 * is supposed to take place anyway.
266 */
267int scm_gc_heap_lock = 0;
268
269/* GC Blocking
270 * Don't pause for collection if this is set -- just
271 * expand the heap.
272 */
0f2d19dd
JB
273int scm_block_gc = 1;
274
0f2d19dd
JB
275/* During collection, this accumulates objects holding
276 * weak references.
277 */
ab4bef85 278SCM scm_weak_vectors;
0f2d19dd
JB
279
280/* GC Statistics Keeping
281 */
f2893a25 282unsigned long scm_cells_allocated = 0;
c014a02e
ML
283unsigned long scm_mallocated = 0;
284unsigned long scm_gc_cells_collected;
c8a1bdc4 285unsigned long scm_gc_cells_collected_1 = 0; /* previous GC yield */
c014a02e
ML
286unsigned long scm_gc_malloc_collected;
287unsigned long scm_gc_ports_collected;
0f2d19dd 288unsigned long scm_gc_time_taken = 0;
c014a02e 289static unsigned long t_before_gc;
c9b0d4b0 290unsigned long scm_gc_mark_time_taken = 0;
c014a02e
ML
291unsigned long scm_gc_times = 0;
292unsigned long scm_gc_cells_swept = 0;
c9b0d4b0
ML
293double scm_gc_cells_marked_acc = 0.;
294double scm_gc_cells_swept_acc = 0.;
c2cbcc57
HWN
295int scm_gc_cell_yield_percentage =0;
296int scm_gc_malloc_yield_percentage = 0;
297
0f2d19dd
JB
298
299SCM_SYMBOL (sym_cells_allocated, "cells-allocated");
300SCM_SYMBOL (sym_heap_size, "cell-heap-size");
301SCM_SYMBOL (sym_mallocated, "bytes-malloced");
302SCM_SYMBOL (sym_mtrigger, "gc-malloc-threshold");
303SCM_SYMBOL (sym_heap_segments, "cell-heap-segments");
304SCM_SYMBOL (sym_gc_time_taken, "gc-time-taken");
c9b0d4b0 305SCM_SYMBOL (sym_gc_mark_time_taken, "gc-mark-time-taken");
c9b0d4b0
ML
306SCM_SYMBOL (sym_times, "gc-times");
307SCM_SYMBOL (sym_cells_marked, "cells-marked");
308SCM_SYMBOL (sym_cells_swept, "cells-swept");
c2cbcc57
HWN
309SCM_SYMBOL (sym_malloc_yield, "malloc-yield");
310SCM_SYMBOL (sym_cell_yield, "cell-yield");
0f2d19dd 311
bb2c57fa 312
cf2d30f6 313
d3dd80ab 314
cf2d30f6 315/* Number of calls to SCM_NEWCELL since startup. */
c8a1bdc4
HWN
316unsigned scm_newcell_count;
317unsigned scm_newcell2_count;
b37fe1c5 318
b37fe1c5 319
0f2d19dd
JB
320/* {Scheme Interface to GC}
321 */
c2cbcc57 322extern int scm_gc_malloc_yield_percentage;
a00c95d9 323SCM_DEFINE (scm_gc_stats, "gc-stats", 0, 0, 0,
1bbd0b84 324 (),
1e6808ea 325 "Return an association list of statistics about Guile's current\n"
c8a1bdc4 326 "use of storage.\n")
1bbd0b84 327#define FUNC_NAME s_scm_gc_stats
0f2d19dd 328{
c8a1bdc4
HWN
329 long i = 0;
330 SCM heap_segs = SCM_EOL ;
c014a02e
ML
331 unsigned long int local_scm_mtrigger;
332 unsigned long int local_scm_mallocated;
333 unsigned long int local_scm_heap_size;
c2cbcc57
HWN
334 int local_scm_gc_cell_yield_percentage;
335 int local_scm_gc_malloc_yield_percentage;
f2893a25 336 unsigned long int local_scm_cells_allocated;
c014a02e
ML
337 unsigned long int local_scm_gc_time_taken;
338 unsigned long int local_scm_gc_times;
339 unsigned long int local_scm_gc_mark_time_taken;
c9b0d4b0
ML
340 double local_scm_gc_cells_swept;
341 double local_scm_gc_cells_marked;
0f2d19dd 342 SCM answer;
c8a1bdc4
HWN
343 unsigned long *bounds = 0;
344 int table_size = scm_i_heap_segment_table_size;
0f2d19dd 345 SCM_DEFER_INTS;
939794ce 346
c8a1bdc4
HWN
347 /*
348 temporarily store the numbers, so as not to cause GC.
7febb4a2 349 */
c8a1bdc4
HWN
350
351 bounds = malloc (sizeof (int) * table_size * 2);
352 if (!bounds)
353 abort();
354 for (i = table_size; i--; )
355 {
356 bounds[2*i] = (unsigned long)scm_i_heap_segment_table[i]->bounds[0];
357 bounds[2*i+1] = (unsigned long)scm_i_heap_segment_table[i]->bounds[1];
358 }
0f2d19dd 359
4c9419ac 360
c8a1bdc4
HWN
361 /* Below, we cons to produce the resulting list. We want a snapshot of
362 * the heap situation before consing.
363 */
364 local_scm_mtrigger = scm_mtrigger;
365 local_scm_mallocated = scm_mallocated;
366 local_scm_heap_size = SCM_HEAP_SIZE;
539b08a4 367
c8a1bdc4
HWN
368 local_scm_cells_allocated = scm_cells_allocated;
369
370 local_scm_gc_time_taken = scm_gc_time_taken;
371 local_scm_gc_mark_time_taken = scm_gc_mark_time_taken;
372 local_scm_gc_times = scm_gc_times;
c2cbcc57
HWN
373 local_scm_gc_malloc_yield_percentage = scm_gc_malloc_yield_percentage;
374 local_scm_gc_cell_yield_percentage= scm_gc_cell_yield_percentage;
375
376 local_scm_gc_cells_swept =
377 (double) scm_gc_cells_swept_acc
378 + (double) scm_gc_cells_swept;
c8a1bdc4
HWN
379 local_scm_gc_cells_marked = scm_gc_cells_marked_acc
380 +(double) scm_gc_cells_swept
381 -(double) scm_gc_cells_collected;
0f2d19dd 382
c8a1bdc4
HWN
383 for (i = table_size; i--;)
384 {
385 heap_segs = scm_cons (scm_cons (scm_ulong2num (bounds[2*i]),
386 scm_ulong2num (bounds[2*i+1])),
387 heap_segs);
388 }
389
390 answer = scm_list_n (scm_cons (sym_gc_time_taken, scm_ulong2num (local_scm_gc_time_taken)),
f2893a25 391 scm_cons (sym_cells_allocated, scm_ulong2num (local_scm_cells_allocated)),
c8a1bdc4
HWN
392 scm_cons (sym_heap_size, scm_ulong2num (local_scm_heap_size)),
393 scm_cons (sym_mallocated, scm_ulong2num (local_scm_mallocated)),
394 scm_cons (sym_mtrigger, scm_ulong2num (local_scm_mtrigger)),
395 scm_cons (sym_times, scm_ulong2num (local_scm_gc_times)),
396 scm_cons (sym_gc_mark_time_taken, scm_ulong2num (local_scm_gc_mark_time_taken)),
397 scm_cons (sym_cells_marked, scm_i_dbl2big (local_scm_gc_cells_marked)),
398 scm_cons (sym_cells_swept, scm_i_dbl2big (local_scm_gc_cells_swept)),
c2cbcc57
HWN
399 scm_cons (sym_malloc_yield, scm_long2num (local_scm_gc_malloc_yield_percentage)),
400 scm_cons (sym_cell_yield, scm_long2num (local_scm_gc_cell_yield_percentage)),
c8a1bdc4
HWN
401 scm_cons (sym_heap_segments, heap_segs),
402 SCM_UNDEFINED);
403 SCM_ALLOW_INTS;
404
405 free (bounds);
406 return answer;
0f2d19dd 407}
c8a1bdc4 408#undef FUNC_NAME
0f2d19dd 409
c8a1bdc4
HWN
410static void
411gc_start_stats (const char *what SCM_UNUSED)
e4a7824f 412{
c8a1bdc4 413 t_before_gc = scm_c_get_internal_run_time ();
539b08a4 414
c8a1bdc4
HWN
415 scm_gc_cells_marked_acc += (double) scm_gc_cells_swept
416 - (double) scm_gc_cells_collected;
c2cbcc57 417 scm_gc_cells_swept_acc += (double) scm_gc_cells_swept;
e4a7824f 418
c2cbcc57
HWN
419 scm_gc_cell_yield_percentage = ( scm_gc_cells_collected * 100 ) / SCM_HEAP_SIZE;
420
c8a1bdc4
HWN
421 scm_gc_cells_swept = 0;
422 scm_gc_cells_collected_1 = scm_gc_cells_collected;
539b08a4 423
c8a1bdc4
HWN
424 /*
425 CELLS SWEPT is another word for the number of cells that were
426 examined during GC. YIELD is the number that we cleaned
427 out. MARKED is the number that weren't cleaned.
428 */
429 scm_gc_cells_collected = 0;
430 scm_gc_malloc_collected = 0;
431 scm_gc_ports_collected = 0;
e4a7824f 432}
acf4331f 433
c8a1bdc4
HWN
434static void
435gc_end_stats ()
0f2d19dd 436{
c8a1bdc4
HWN
437 unsigned long t = scm_c_get_internal_run_time ();
438 scm_gc_time_taken += (t - t_before_gc);
539b08a4 439
c8a1bdc4 440 ++scm_gc_times;
0f2d19dd 441}
acf4331f 442
0f2d19dd 443
c8a1bdc4
HWN
444SCM_DEFINE (scm_object_address, "object-address", 1, 0, 0,
445 (SCM obj),
446 "Return an integer that for the lifetime of @var{obj} is uniquely\n"
447 "returned by this function for @var{obj}")
448#define FUNC_NAME s_scm_object_address
c68296f8 449{
c8a1bdc4 450 return scm_ulong2num ((unsigned long) SCM_UNPACK (obj));
c68296f8 451}
c8a1bdc4 452#undef FUNC_NAME
c68296f8 453
1be6b49c 454
c8a1bdc4
HWN
455SCM_DEFINE (scm_gc, "gc", 0, 0, 0,
456 (),
457 "Scans all of SCM objects and reclaims for further use those that are\n"
458 "no longer accessible.")
459#define FUNC_NAME s_scm_gc
460{
461 SCM_DEFER_INTS;
9bc4701c 462 scm_i_thread_put_to_sleep ();
c8a1bdc4 463 scm_igc ("call");
9bc4701c 464 scm_i_thread_wake_up ();
c8a1bdc4
HWN
465 SCM_ALLOW_INTS;
466 return SCM_UNSPECIFIED;
9d47a1e6 467}
c8a1bdc4 468#undef FUNC_NAME
9d47a1e6 469
c68296f8
MV
470
471\f
0f2d19dd 472
c8a1bdc4
HWN
473/* When we get POSIX threads support, the master will be global and
474 * common while the freelist will be individual for each thread.
0f2d19dd
JB
475 */
476
c8a1bdc4
HWN
477SCM
478scm_gc_for_newcell (scm_t_cell_type_statistics *freelist, SCM *free_cells)
0f2d19dd 479{
c8a1bdc4
HWN
480 SCM cell;
481
9bc4701c
MD
482 scm_i_thread_put_to_sleep ();
483
c8a1bdc4 484 ++scm_ints_disabled;
0f2d19dd 485
c8a1bdc4
HWN
486 *free_cells = scm_i_sweep_some_segments (freelist);
487 if (*free_cells == SCM_EOL && scm_i_gc_grow_heap_p (freelist))
488 {
489 freelist->heap_segment_idx = scm_i_get_new_heap_segment (freelist, abort_on_error);
490 *free_cells = scm_i_sweep_some_segments (freelist);
491 }
acb0a19c 492
c8a1bdc4
HWN
493 if (*free_cells == SCM_EOL && !scm_block_gc)
494 {
495 /*
496 with the advent of lazy sweep, GC yield is only know just
497 before doing the GC.
498 */
499 scm_i_adjust_min_yield (freelist);
500
501 /*
502 out of fresh cells. Try to get some new ones.
503 */
0f2d19dd 504
c8a1bdc4 505 scm_igc ("cells");
a00c95d9 506
c8a1bdc4
HWN
507 *free_cells = scm_i_sweep_some_segments (freelist);
508 }
509
510 if (*free_cells == SCM_EOL)
511 {
512 /*
513 failed getting new cells. Get new juice or die.
514 */
515 freelist->heap_segment_idx = scm_i_get_new_heap_segment (freelist, abort_on_error);
516 *free_cells = scm_i_sweep_some_segments (freelist);
517 }
518
519 if (*free_cells == SCM_EOL)
520 abort ();
0f2d19dd 521
c8a1bdc4 522 cell = *free_cells;
0f2d19dd 523
c8a1bdc4 524 --scm_ints_disabled;
0f2d19dd 525
c8a1bdc4 526 *free_cells = SCM_FREE_CELL_CDR (cell);
eab1b259 527
9bc4701c 528 scm_i_thread_wake_up ();
eab1b259 529
c8a1bdc4
HWN
530 return cell;
531}
4a4c9785 532
4a4c9785 533
c8a1bdc4
HWN
534scm_t_c_hook scm_before_gc_c_hook;
535scm_t_c_hook scm_before_mark_c_hook;
536scm_t_c_hook scm_before_sweep_c_hook;
537scm_t_c_hook scm_after_sweep_c_hook;
538scm_t_c_hook scm_after_gc_c_hook;
4a4c9785 539
c8a1bdc4
HWN
540void
541scm_igc (const char *what)
542{
543 ++scm_gc_running_p;
544 scm_c_hook_run (&scm_before_gc_c_hook, 0);
a00c95d9 545
c8a1bdc4
HWN
546#ifdef DEBUGINFO
547 fprintf (stderr,"gc reason %s\n", what);
548
549 fprintf (stderr,
9bc4701c 550 SCM_NULLP (*SCM_FREELIST_LOC (scm_i_freelist))
c8a1bdc4 551 ? "*"
9bc4701c 552 : (SCM_NULLP (*SCM_FREELIST_LOC (scm_i_freelist2)) ? "o" : "m"));
c8a1bdc4 553#endif
4c48ba06 554
c8a1bdc4 555 /* During the critical section, only the current thread may run. */
9bc4701c
MD
556#if 0 /* MDJ 021207 <djurfeldt@nada.kth.se>
557 Currently, a much larger piece of the GC is single threaded.
558 Can we shrink it again? */
c8a1bdc4 559 SCM_CRITICAL_SECTION_START;
9bc4701c 560#endif
a00c95d9 561
eab1b259 562 if (!scm_root || !scm_stack_base || scm_block_gc)
d6884e63 563 {
c8a1bdc4
HWN
564 --scm_gc_running_p;
565 return;
d6884e63
ML
566 }
567
c8a1bdc4 568 gc_start_stats (what);
a00c95d9 569
c8a1bdc4
HWN
570 if (scm_gc_heap_lock)
571 /* We've invoked the collector while a GC is already in progress.
572 That should never happen. */
573 abort ();
a00c95d9 574
c8a1bdc4 575 ++scm_gc_heap_lock;
a00c95d9 576
c8a1bdc4
HWN
577 /*
578 Let's finish the sweep. The conservative GC might point into the
579 garbage, and marking that would create a mess.
580 */
581 scm_i_sweep_all_segments("GC");
582 if (scm_mallocated < scm_i_deprecated_memory_return)
b6efc951 583 {
c8a1bdc4
HWN
584 /* The byte count of allocated objects has underflowed. This is
585 probably because you forgot to report the sizes of objects you
586 have allocated, by calling scm_done_malloc or some such. When
587 the GC freed them, it subtracted their size from
588 scm_mallocated, which underflowed. */
589 fprintf (stderr,
590 "scm_gc_sweep: Byte count of allocated objects has underflowed.\n"
591 "This is probably because the GC hasn't been correctly informed\n"
592 "about object sizes\n");
b6efc951
DH
593 abort ();
594 }
c8a1bdc4 595 scm_mallocated -= scm_i_deprecated_memory_return;
0f2d19dd 596
c8a1bdc4
HWN
597
598
599 scm_c_hook_run (&scm_before_mark_c_hook, 0);
b6efc951 600
c8a1bdc4
HWN
601 scm_mark_all ();
602
c2cbcc57 603 scm_gc_mark_time_taken += (scm_c_get_internal_run_time () - t_before_gc);
c8a1bdc4
HWN
604
605 scm_c_hook_run (&scm_before_sweep_c_hook, 0);
606
607 /*
608 Moved this lock upwards so that we can alloc new heap at the end of a sweep.
0f2d19dd 609
c8a1bdc4 610 DOCME: why should the heap be locked anyway?
0f2d19dd 611 */
c8a1bdc4 612 --scm_gc_heap_lock;
a00c95d9 613
c8a1bdc4 614 scm_gc_sweep ();
0f2d19dd 615
ffd72400
HWN
616
617 /*
618 TODO: this hook should probably be moved to just before the mark,
619 since that's where the sweep is finished in lazy sweeping.
620 */
c8a1bdc4
HWN
621 scm_c_hook_run (&scm_after_sweep_c_hook, 0);
622 gc_end_stats ();
623
9bc4701c 624#if 0 /* MDJ 021207 <djurfeldt@nada.kth.se> */
c8a1bdc4 625 SCM_CRITICAL_SECTION_END;
9bc4701c 626#endif
ffd72400
HWN
627
628 /*
629 See above.
630 */
c8a1bdc4
HWN
631 scm_c_hook_run (&scm_after_gc_c_hook, 0);
632 --scm_gc_running_p;
a00c95d9 633
eab1b259
HWN
634 /*
635 For debugging purposes, you could do
636 scm_i_sweep_all_segments("debug"), but then the remains of the
637 cell aren't left to analyse.
638 */
639}
0f2d19dd 640
0f2d19dd
JB
641\f
642/* {GC Protection Helper Functions}
643 */
644
645
5d2b97cd
DH
646/*
647 * If within a function you need to protect one or more scheme objects from
648 * garbage collection, pass them as parameters to one of the
649 * scm_remember_upto_here* functions below. These functions don't do
650 * anything, but since the compiler does not know that they are actually
651 * no-ops, it will generate code that calls these functions with the given
652 * parameters. Therefore, you can be sure that the compiler will keep those
653 * scheme values alive (on the stack or in a register) up to the point where
654 * scm_remember_upto_here* is called. In other words, place the call to
592996c9 655 * scm_remember_upto_here* _behind_ the last code in your function, that
5d2b97cd
DH
656 * depends on the scheme object to exist.
657 *
8c494e99
DH
658 * Example: We want to make sure that the string object str does not get
659 * garbage collected during the execution of 'some_function' in the code
660 * below, because otherwise the characters belonging to str would be freed and
5d2b97cd
DH
661 * 'some_function' might access freed memory. To make sure that the compiler
662 * keeps str alive on the stack or in a register such that it is visible to
663 * the conservative gc we add the call to scm_remember_upto_here_1 _after_ the
664 * call to 'some_function'. Note that this would not be necessary if str was
665 * used anyway after the call to 'some_function'.
666 * char *chars = SCM_STRING_CHARS (str);
667 * some_function (chars);
668 * scm_remember_upto_here_1 (str); // str will be alive up to this point.
669 */
670
671void
e81d98ec 672scm_remember_upto_here_1 (SCM obj SCM_UNUSED)
5d2b97cd
DH
673{
674 /* Empty. Protects a single object from garbage collection. */
675}
676
677void
e81d98ec 678scm_remember_upto_here_2 (SCM obj1 SCM_UNUSED, SCM obj2 SCM_UNUSED)
5d2b97cd
DH
679{
680 /* Empty. Protects two objects from garbage collection. */
681}
682
683void
e81d98ec 684scm_remember_upto_here (SCM obj SCM_UNUSED, ...)
5d2b97cd
DH
685{
686 /* Empty. Protects any number of objects from garbage collection. */
687}
688
c209c88e 689/*
41b0806d
GB
690 These crazy functions prevent garbage collection
691 of arguments after the first argument by
692 ensuring they remain live throughout the
693 function because they are used in the last
694 line of the code block.
695 It'd be better to have a nice compiler hint to
696 aid the conservative stack-scanning GC. --03/09/00 gjb */
0f2d19dd
JB
697SCM
698scm_return_first (SCM elt, ...)
0f2d19dd
JB
699{
700 return elt;
701}
702
41b0806d
GB
703int
704scm_return_first_int (int i, ...)
705{
706 return i;
707}
708
0f2d19dd 709
0f2d19dd 710SCM
6e8d25a6 711scm_permanent_object (SCM obj)
0f2d19dd
JB
712{
713 SCM_REDEFER_INTS;
714 scm_permobjs = scm_cons (obj, scm_permobjs);
715 SCM_REALLOW_INTS;
716 return obj;
717}
718
719
7bd4fbe2
MD
720/* Protect OBJ from the garbage collector. OBJ will not be freed, even if all
721 other references are dropped, until the object is unprotected by calling
6b1b030e 722 scm_gc_unprotect_object (OBJ). Calls to scm_gc_protect/unprotect_object nest,
7bd4fbe2
MD
723 i. e. it is possible to protect the same object several times, but it is
724 necessary to unprotect the object the same number of times to actually get
725 the object unprotected. It is an error to unprotect an object more often
726 than it has been protected before. The function scm_protect_object returns
727 OBJ.
728*/
729
730/* Implementation note: For every object X, there is a counter which
6b1b030e 731 scm_gc_protect_object(X) increments and scm_gc_unprotect_object(X) decrements.
7bd4fbe2 732*/
686765af 733
ef290276 734SCM
6b1b030e 735scm_gc_protect_object (SCM obj)
ef290276 736{
686765af 737 SCM handle;
9d47a1e6 738
686765af 739 /* This critical section barrier will be replaced by a mutex. */
2dd6a83a 740 SCM_REDEFER_INTS;
9d47a1e6 741
0f0f0899 742 handle = scm_hashq_create_handle_x (scm_protects, obj, SCM_MAKINUM (0));
1be6b49c 743 SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), SCM_MAKINUM (1)));
9d47a1e6 744
2dd6a83a 745 SCM_REALLOW_INTS;
9d47a1e6 746
ef290276
JB
747 return obj;
748}
749
750
751/* Remove any protection for OBJ established by a prior call to
dab7f566 752 scm_protect_object. This function returns OBJ.
ef290276 753
dab7f566 754 See scm_protect_object for more information. */
ef290276 755SCM
6b1b030e 756scm_gc_unprotect_object (SCM obj)
ef290276 757{
686765af 758 SCM handle;
9d47a1e6 759
686765af 760 /* This critical section barrier will be replaced by a mutex. */
2dd6a83a 761 SCM_REDEFER_INTS;
9d47a1e6 762
686765af 763 handle = scm_hashq_get_handle (scm_protects, obj);
9d47a1e6 764
22a52da1 765 if (SCM_FALSEP (handle))
686765af 766 {
0f0f0899
MD
767 fprintf (stderr, "scm_unprotect_object called on unprotected object\n");
768 abort ();
686765af 769 }
6a199940
DH
770 else
771 {
1be6b49c
ML
772 SCM count = scm_difference (SCM_CDR (handle), SCM_MAKINUM (1));
773 if (SCM_EQ_P (count, SCM_MAKINUM (0)))
6a199940
DH
774 scm_hashq_remove_x (scm_protects, obj);
775 else
1be6b49c 776 SCM_SETCDR (handle, count);
6a199940 777 }
686765af 778
2dd6a83a 779 SCM_REALLOW_INTS;
ef290276
JB
780
781 return obj;
782}
783
6b1b030e
ML
784void
785scm_gc_register_root (SCM *p)
786{
787 SCM handle;
788 SCM key = scm_long2num ((long) p);
eae33935 789
6b1b030e
ML
790 /* This critical section barrier will be replaced by a mutex. */
791 SCM_REDEFER_INTS;
792
793 handle = scm_hashv_create_handle_x (scm_gc_registered_roots, key, SCM_MAKINUM (0));
794 SCM_SETCDR (handle, scm_sum (SCM_CDR (handle), SCM_MAKINUM (1)));
795
796 SCM_REALLOW_INTS;
797}
798
799void
800scm_gc_unregister_root (SCM *p)
801{
802 SCM handle;
803 SCM key = scm_long2num ((long) p);
804
805 /* This critical section barrier will be replaced by a mutex. */
806 SCM_REDEFER_INTS;
807
808 handle = scm_hashv_get_handle (scm_gc_registered_roots, key);
809
810 if (SCM_FALSEP (handle))
811 {
812 fprintf (stderr, "scm_gc_unregister_root called on unregistered root\n");
813 abort ();
814 }
815 else
816 {
817 SCM count = scm_difference (SCM_CDR (handle), SCM_MAKINUM (1));
818 if (SCM_EQ_P (count, SCM_MAKINUM (0)))
819 scm_hashv_remove_x (scm_gc_registered_roots, key);
820 else
821 SCM_SETCDR (handle, count);
822 }
823
824 SCM_REALLOW_INTS;
825}
826
827void
828scm_gc_register_roots (SCM *b, unsigned long n)
829{
830 SCM *p = b;
831 for (; p < b + n; ++p)
832 scm_gc_register_root (p);
833}
834
835void
836scm_gc_unregister_roots (SCM *b, unsigned long n)
837{
838 SCM *p = b;
839 for (; p < b + n; ++p)
840 scm_gc_unregister_root (p);
841}
842
04a98cff 843int scm_i_terminating;
c45acc34
JB
844
845/* called on process termination. */
e52ceaac
MD
846#ifdef HAVE_ATEXIT
847static void
848cleanup (void)
849#else
850#ifdef HAVE_ON_EXIT
51157deb
MD
851extern int on_exit (void (*procp) (), int arg);
852
e52ceaac
MD
853static void
854cleanup (int status, void *arg)
855#else
856#error Dont know how to setup a cleanup handler on your system.
857#endif
858#endif
c45acc34 859{
04a98cff 860 scm_i_terminating = 1;
c45acc34
JB
861 scm_flush_all_ports ();
862}
ef290276 863
0f2d19dd 864\f
a00c95d9 865
4c48ba06 866
c8a1bdc4
HWN
867/*
868 MOVE THIS FUNCTION. IT DOES NOT HAVE ANYTHING TODO WITH GC.
869 */
85db4a2c
DH
870
871/* Get an integer from an environment variable. */
c8a1bdc4
HWN
872int
873scm_getenv_int (const char *var, int def)
85db4a2c 874{
c8a1bdc4
HWN
875 char *end = 0;
876 char *val = getenv (var);
877 long res = def;
85db4a2c
DH
878 if (!val)
879 return def;
880 res = strtol (val, &end, 10);
881 if (end == val)
882 return def;
883 return res;
884}
885
886
4a4c9785 887int
85db4a2c 888scm_init_storage ()
0f2d19dd 889{
1be6b49c 890 size_t j;
0f2d19dd
JB
891
892 j = SCM_NUM_PROTECTS;
893 while (j)
894 scm_sys_protects[--j] = SCM_BOOL_F;
895 scm_block_gc = 1;
4a4c9785 896
c8a1bdc4
HWN
897 scm_gc_init_freelist();
898 scm_gc_init_malloc ();
0f2d19dd
JB
899
900 j = SCM_HEAP_SEG_SIZE;
d6884e63 901
c8a1bdc4 902
acb0a19c 903
801cb5e7
MD
904 scm_c_hook_init (&scm_before_gc_c_hook, 0, SCM_C_HOOK_NORMAL);
905 scm_c_hook_init (&scm_before_mark_c_hook, 0, SCM_C_HOOK_NORMAL);
906 scm_c_hook_init (&scm_before_sweep_c_hook, 0, SCM_C_HOOK_NORMAL);
907 scm_c_hook_init (&scm_after_sweep_c_hook, 0, SCM_C_HOOK_NORMAL);
908 scm_c_hook_init (&scm_after_gc_c_hook, 0, SCM_C_HOOK_NORMAL);
0f2d19dd
JB
909
910 /* Initialise the list of ports. */
67329a9e
HWN
911 scm_i_port_table = (scm_t_port **)
912 malloc (sizeof (scm_t_port *) * scm_i_port_table_room);
913 if (!scm_i_port_table)
0f2d19dd
JB
914 return 1;
915
a18bcd0e 916#ifdef HAVE_ATEXIT
c45acc34 917 atexit (cleanup);
e52ceaac
MD
918#else
919#ifdef HAVE_ON_EXIT
920 on_exit (cleanup, 0);
921#endif
a18bcd0e 922#endif
0f2d19dd 923
8960e0a0 924 scm_stand_in_procs = SCM_EOL;
0f2d19dd 925 scm_permobjs = SCM_EOL;
00ffa0e7 926 scm_protects = scm_c_make_hash_table (31);
6b1b030e 927 scm_gc_registered_roots = scm_c_make_hash_table (31);
d6884e63 928
0f2d19dd
JB
929 return 0;
930}
939794ce 931
0f2d19dd
JB
932\f
933
939794ce
DH
934SCM scm_after_gc_hook;
935
939794ce
DH
936static SCM gc_async;
937
939794ce
DH
938/* The function gc_async_thunk causes the execution of the after-gc-hook. It
939 * is run after the gc, as soon as the asynchronous events are handled by the
940 * evaluator.
941 */
942static SCM
943gc_async_thunk (void)
944{
945 scm_c_run_hook (scm_after_gc_hook, SCM_EOL);
939794ce
DH
946 return SCM_UNSPECIFIED;
947}
948
949
950/* The function mark_gc_async is run by the scm_after_gc_c_hook at the end of
951 * the garbage collection. The only purpose of this function is to mark the
952 * gc_async (which will eventually lead to the execution of the
953 * gc_async_thunk).
954 */
955static void *
e81d98ec
DH
956mark_gc_async (void * hook_data SCM_UNUSED,
957 void *func_data SCM_UNUSED,
958 void *data SCM_UNUSED)
959{
960 /* If cell access debugging is enabled, the user may choose to perform
961 * additional garbage collections after an arbitrary number of cell
962 * accesses. We don't want the scheme level after-gc-hook to be performed
963 * for each of these garbage collections for the following reason: The
964 * execution of the after-gc-hook causes cell accesses itself. Thus, if the
965 * after-gc-hook was performed with every gc, and if the gc was performed
966 * after a very small number of cell accesses, then the number of cell
967 * accesses during the execution of the after-gc-hook will suffice to cause
968 * the execution of the next gc. Then, guile would keep executing the
969 * after-gc-hook over and over again, and would never come to do other
970 * things.
eae33935 971 *
e81d98ec
DH
972 * To overcome this problem, if cell access debugging with additional
973 * garbage collections is enabled, the after-gc-hook is never run by the
974 * garbage collecter. When running guile with cell access debugging and the
975 * execution of the after-gc-hook is desired, then it is necessary to run
976 * the hook explicitly from the user code. This has the effect, that from
977 * the scheme level point of view it seems that garbage collection is
978 * performed with a much lower frequency than it actually is. Obviously,
979 * this will not work for code that depends on a fixed one to one
980 * relationship between the execution counts of the C level garbage
981 * collection hooks and the execution count of the scheme level
982 * after-gc-hook.
983 */
984#if (SCM_DEBUG_CELL_ACCESSES == 1)
eab1b259 985 if (scm_debug_cells_gc_interval == 0)
e81d98ec
DH
986 scm_system_async_mark (gc_async);
987#else
939794ce 988 scm_system_async_mark (gc_async);
e81d98ec
DH
989#endif
990
939794ce
DH
991 return NULL;
992}
993
0f2d19dd
JB
994void
995scm_init_gc ()
0f2d19dd 996{
c8a1bdc4 997 scm_gc_init_mark ();
d678e25c 998
fde50407
ML
999 scm_after_gc_hook = scm_permanent_object (scm_make_hook (SCM_INUM0));
1000 scm_c_define ("after-gc-hook", scm_after_gc_hook);
939794ce 1001
2592c4c7
MV
1002 gc_async = scm_c_make_subr ("%gc-thunk", scm_tc7_subr_0,
1003 gc_async_thunk);
939794ce
DH
1004
1005 scm_c_hook_add (&scm_after_gc_c_hook, mark_gc_async, NULL, 0);
1006
a0599745 1007#include "libguile/gc.x"
0f2d19dd 1008}
89e00824 1009
c8a1bdc4
HWN
1010
1011void
1012scm_gc_sweep (void)
1013#define FUNC_NAME "scm_gc_sweep"
1014{
1015 scm_i_deprecated_memory_return = 0;
1016
1017 scm_i_gc_sweep_freelist_reset (&scm_i_master_freelist);
1018 scm_i_gc_sweep_freelist_reset (&scm_i_master_freelist2);
1019
1020 /*
1021 NOTHING HERE: LAZY SWEEPING !
1022 */
1023 scm_i_reset_segments ();
1024
1025 /* When we move to POSIX threads private freelists should probably
1026 be GC-protected instead. */
9bc4701c
MD
1027 *SCM_FREELIST_LOC (scm_i_freelist) = SCM_EOL;
1028 *SCM_FREELIST_LOC (scm_i_freelist2) = SCM_EOL;
c8a1bdc4
HWN
1029}
1030
1031#undef FUNC_NAME
1032
1033
56495472 1034
89e00824
ML
1035/*
1036 Local Variables:
1037 c-file-style: "gnu"
1038 End:
1039*/