Use string and symbol accessors in struct, throw, and array funcs
[bpt/guile.git] / libguile / gc-freelist.c
CommitLineData
dbb605f5 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2002, 2006, 2008 Free Software Foundation, Inc.
c7743d02 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
c7743d02 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
c7743d02 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
c7743d02 18
dbb605f5
LC
19#ifdef HAVE_CONFIG_H
20# include <config.h>
21#endif
22
c7743d02 23#include <assert.h>
5bd4a949 24#include <stdio.h>
c7743d02
HWN
25
26#include "libguile/private-gc.h"
27#include "libguile/gc.h"
28#include "libguile/deprecation.h"
29#include "libguile/private-gc.h"
30
31scm_t_cell_type_statistics scm_i_master_freelist;
32scm_t_cell_type_statistics scm_i_master_freelist2;
33
c7743d02
HWN
34/*
35
36In older versions of GUILE GC there was extensive support for
37debugging freelists. This was useful, since the freelist was kept
38inside the heap, and writing to an object that was GC'd would mangle
39the list. Mark bits are now separate, and checking for sane cell
40access can be done much more easily by simply checking if the mark bit
41is unset before allocation. --hwn
42
c7743d02
HWN
43*/
44
45#if (SCM_ENABLE_DEPRECATED == 1)
46#if defined(GUILE_DEBUG_FREELIST)
47
48SCM_DEFINE (scm_map_free_list, "map-free-list", 0, 0, 0,
49 (),
50 "DEPRECATED\n")
2e945bcc 51#define FUNC_NAME "s_scm_map_free_list"
c7743d02
HWN
52{
53 scm_c_issue_deprecation_warning ("map-free-list has been removed from GUILE. Doing nothing\n");
54 return SCM_UNSPECIFIED;
55}
2e945bcc 56#undef FUNC_NAME
c7743d02
HWN
57
58SCM_DEFINE (scm_gc_set_debug_check_freelist_x, "gc-set-debug-check-freelist!", 1, 0, 0,
59 (SCM flag),
60 "DEPRECATED.\n")
2e945bcc 61#define FUNC_NAME "s_scm_gc_set_debug_check_freelist_x"
c7743d02
HWN
62{
63 scm_c_issue_deprecation_warning ("gc-set-debug-check-freelist! has been removed from GUILE. Doing nothing\n");
64 return SCM_UNSPECIFIED;
65}
66#undef FUNC_NAME
67
68
69#endif /* defined (GUILE_DEBUG) */
70#endif /* deprecated */
71
c7743d02
HWN
72static void
73scm_init_freelist (scm_t_cell_type_statistics *freelist,
82ae1b8e
HWN
74 int span,
75 int min_yield_percentage)
c7743d02 76{
82ae1b8e
HWN
77 if (min_yield_percentage < 1)
78 min_yield_percentage = 1;
79 if (min_yield_percentage > 99)
80 min_yield_percentage = 99;
dac04e9f 81
c7743d02 82 freelist->heap_segment_idx = -1;
82ae1b8e 83 freelist->min_yield_fraction = min_yield_percentage / 100.0;
c7743d02 84 freelist->span = span;
82ae1b8e 85 freelist->swept = 0;
c7743d02 86 freelist->collected = 0;
82ae1b8e 87 freelist->heap_total_cells = 0;
c7743d02
HWN
88}
89
90#if (SCM_ENABLE_DEPRECATED == 1)
82ae1b8e
HWN
91size_t scm_default_init_heap_size_1;
92int scm_default_min_yield_1;
93size_t scm_default_init_heap_size_2;
94int scm_default_min_yield_2;
95size_t scm_default_max_segment_size;
96
97static void
98check_deprecated_heap_vars (void) {
99 if (scm_default_init_heap_size_1 ||
100 scm_default_min_yield_1||
101 scm_default_init_heap_size_2||
102 scm_default_min_yield_2||
103 scm_default_max_segment_size)
104 {
105 scm_c_issue_deprecation_warning ("Tuning heap parameters with C variables is deprecated. Use environment variables instead.");
106 }
107}
108#else
109static void check_deprecated_heap_vars (void) { }
c7743d02
HWN
110#endif
111
112void
113scm_gc_init_freelist (void)
114{
82ae1b8e
HWN
115 const char *error_message =
116 "Could not allocate initial heap of %uld.\n"
117 "Try adjusting GUILE_INIT_SEGMENT_SIZE_%d\n";
118
dac04e9f 119 int init_heap_size_1
c7743d02 120 = scm_getenv_int ("GUILE_INIT_SEGMENT_SIZE_1", SCM_DEFAULT_INIT_HEAP_SIZE_1);
dac04e9f 121 int init_heap_size_2
c7743d02
HWN
122 = scm_getenv_int ("GUILE_INIT_SEGMENT_SIZE_2", SCM_DEFAULT_INIT_HEAP_SIZE_2);
123
c7743d02
HWN
124 scm_init_freelist (&scm_i_master_freelist2, 2,
125 scm_getenv_int ("GUILE_MIN_YIELD_2", SCM_DEFAULT_MIN_YIELD_2));
126 scm_init_freelist (&scm_i_master_freelist, 1,
127 scm_getenv_int ("GUILE_MIN_YIELD_1", SCM_DEFAULT_MIN_YIELD_1));
128
c7743d02 129 scm_max_segment_size = scm_getenv_int ("GUILE_MAX_SEGMENT_SIZE", SCM_DEFAULT_MAX_SEGMENT_SIZE);
dac04e9f
HWN
130
131 if (scm_max_segment_size <= 0)
132 scm_max_segment_size = SCM_DEFAULT_MAX_SEGMENT_SIZE;
82ae1b8e
HWN
133
134 if (scm_i_get_new_heap_segment (&scm_i_master_freelist,
135 init_heap_size_1, return_on_error) == -1) {
136 fprintf (stderr, error_message, init_heap_size_1, 1);
1f584400 137 abort ();
82ae1b8e
HWN
138 }
139 if (scm_i_get_new_heap_segment (&scm_i_master_freelist2,
140 init_heap_size_2, return_on_error) == -1) {
141 fprintf (stderr, error_message, init_heap_size_2, 2);
1f584400 142 abort ();
82ae1b8e
HWN
143 }
144
1f584400 145 check_deprecated_heap_vars ();
c7743d02
HWN
146}
147
148
82ae1b8e 149
c7743d02
HWN
150void
151scm_i_gc_sweep_freelist_reset (scm_t_cell_type_statistics *freelist)
152{
c7743d02 153 freelist->collected = 0;
82ae1b8e 154 freelist->swept = 0;
c7743d02
HWN
155 /*
156 at the end we simply start with the lowest segment again.
157 */
158 freelist->heap_segment_idx = -1;
159}
160
82ae1b8e
HWN
161
162/*
163 Returns how many more cells we should allocate according to our
164 policy. May return negative if we don't need to allocate more.
165
166
167 The new yield should at least equal gc fraction of new heap size, i.e.
168
169 c + dh > f * (h + dh)
170
171 c : collected
172 f : min yield fraction
173 h : heap size
174 dh : size of new heap segment
175
176 this gives dh > (f * h - c) / (1 - f).
177*/
178float
179scm_i_gc_heap_size_delta (scm_t_cell_type_statistics * freelist)
c7743d02 180{
82ae1b8e
HWN
181 float f = freelist->min_yield_fraction;
182 float collected = freelist->collected;
183 float swept = freelist->swept;
184 float delta = ((f * swept - collected) / (1.0 - f));
185
e0b20b68 186#if 0
1f584400
HWN
187 assert (freelist->heap_total_cells >= freelist->collected);
188 assert (freelist->swept == freelist->heap_total_cells);
189 assert (swept >= collected);
e0b20b68 190#endif
82ae1b8e
HWN
191
192 return delta;
c7743d02 193}