1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library 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 GNU
11 * Lesser General Public License for more details.
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 02110-1301 USA
25 #include "libguile/private-gc.h"
26 #include "libguile/gc.h"
27 #include "libguile/deprecation.h"
28 #include "libguile/private-gc.h"
30 scm_t_cell_type_statistics scm_i_master_freelist
;
31 scm_t_cell_type_statistics scm_i_master_freelist2
;
35 In older versions of GUILE GC there was extensive support for
36 debugging freelists. This was useful, since the freelist was kept
37 inside the heap, and writing to an object that was GC'd would mangle
38 the list. Mark bits are now separate, and checking for sane cell
39 access can be done much more easily by simply checking if the mark bit
40 is unset before allocation. --hwn
44 #if (SCM_ENABLE_DEPRECATED == 1)
45 #if defined(GUILE_DEBUG_FREELIST)
47 SCM_DEFINE (scm_map_free_list
, "map-free-list", 0, 0, 0,
50 #define FUNC_NAME "s_scm_map_free_list"
52 scm_c_issue_deprecation_warning ("map-free-list has been removed from GUILE. Doing nothing\n");
53 return SCM_UNSPECIFIED
;
57 SCM_DEFINE (scm_gc_set_debug_check_freelist_x
, "gc-set-debug-check-freelist!", 1, 0, 0,
60 #define FUNC_NAME "s_scm_gc_set_debug_check_freelist_x"
62 scm_c_issue_deprecation_warning ("gc-set-debug-check-freelist! has been removed from GUILE. Doing nothing\n");
63 return SCM_UNSPECIFIED
;
68 #endif /* defined (GUILE_DEBUG) */
69 #endif /* deprecated */
72 scm_init_freelist (scm_t_cell_type_statistics
*freelist
,
74 int min_yield_percentage
)
76 if (min_yield_percentage
< 1)
77 min_yield_percentage
= 1;
78 if (min_yield_percentage
> 99)
79 min_yield_percentage
= 99;
81 freelist
->heap_segment_idx
= -1;
82 freelist
->min_yield_fraction
= min_yield_percentage
/ 100.0;
83 freelist
->span
= span
;
85 freelist
->collected
= 0;
86 freelist
->heap_total_cells
= 0;
89 #if (SCM_ENABLE_DEPRECATED == 1)
90 size_t scm_default_init_heap_size_1
;
91 int scm_default_min_yield_1
;
92 size_t scm_default_init_heap_size_2
;
93 int scm_default_min_yield_2
;
94 size_t scm_default_max_segment_size
;
97 check_deprecated_heap_vars (void) {
98 if (scm_default_init_heap_size_1
||
99 scm_default_min_yield_1
||
100 scm_default_init_heap_size_2
||
101 scm_default_min_yield_2
||
102 scm_default_max_segment_size
)
104 scm_c_issue_deprecation_warning ("Tuning heap parameters with C variables is deprecated. Use environment variables instead.");
108 static void check_deprecated_heap_vars (void) { }
112 scm_gc_init_freelist (void)
114 const char *error_message
=
115 "Could not allocate initial heap of %uld.\n"
116 "Try adjusting GUILE_INIT_SEGMENT_SIZE_%d\n";
119 = scm_getenv_int ("GUILE_INIT_SEGMENT_SIZE_1", SCM_DEFAULT_INIT_HEAP_SIZE_1
);
121 = scm_getenv_int ("GUILE_INIT_SEGMENT_SIZE_2", SCM_DEFAULT_INIT_HEAP_SIZE_2
);
123 scm_init_freelist (&scm_i_master_freelist2
, 2,
124 scm_getenv_int ("GUILE_MIN_YIELD_2", SCM_DEFAULT_MIN_YIELD_2
));
125 scm_init_freelist (&scm_i_master_freelist
, 1,
126 scm_getenv_int ("GUILE_MIN_YIELD_1", SCM_DEFAULT_MIN_YIELD_1
));
128 scm_max_segment_size
= scm_getenv_int ("GUILE_MAX_SEGMENT_SIZE", SCM_DEFAULT_MAX_SEGMENT_SIZE
);
130 if (scm_max_segment_size
<= 0)
131 scm_max_segment_size
= SCM_DEFAULT_MAX_SEGMENT_SIZE
;
133 if (scm_i_get_new_heap_segment (&scm_i_master_freelist
,
134 init_heap_size_1
, return_on_error
) == -1) {
135 fprintf (stderr
, error_message
, init_heap_size_1
, 1);
138 if (scm_i_get_new_heap_segment (&scm_i_master_freelist2
,
139 init_heap_size_2
, return_on_error
) == -1) {
140 fprintf (stderr
, error_message
, init_heap_size_2
, 2);
144 check_deprecated_heap_vars ();
150 scm_i_gc_sweep_freelist_reset (scm_t_cell_type_statistics
*freelist
)
152 freelist
->collected
= 0;
155 at the end we simply start with the lowest segment again.
157 freelist
->heap_segment_idx
= -1;
162 Returns how many more cells we should allocate according to our
163 policy. May return negative if we don't need to allocate more.
166 The new yield should at least equal gc fraction of new heap size, i.e.
168 c + dh > f * (h + dh)
171 f : min yield fraction
173 dh : size of new heap segment
175 this gives dh > (f * h - c) / (1 - f).
178 scm_i_gc_heap_size_delta (scm_t_cell_type_statistics
* freelist
)
180 float f
= freelist
->min_yield_fraction
;
181 float collected
= freelist
->collected
;
182 float swept
= freelist
->swept
;
183 float delta
= ((f
* swept
- collected
) / (1.0 - f
));
185 assert (freelist
->heap_total_cells
>= freelist
->collected
);
186 assert (freelist
->swept
== freelist
->heap_total_cells
);
187 assert (swept
>= collected
);