New versions of the GPLand LGPL with the new address of the FSF.
[bpt/guile.git] / libguile / inline.h
CommitLineData
16ea9620
MV
1/* classes: h_files */
2
3#ifndef SCM_INLINE_H
4#define SCM_INLINE_H
5
d2e53ed6 6/* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
16ea9620 7 *
73be1d9e
MV
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
16ea9620 12 *
73be1d9e 13 * This library is distributed in the hope that it will be useful,
16ea9620 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
16ea9620 17 *
73be1d9e
MV
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
16ea9620
MV
22
23/* This file is for inline functions. On platforms that don't support
24 inlining functions, they are turned into ordinary functions. See
25 "inline.c".
26*/
27
60e7529a 28#include "libguile/__scm.h"
c8a1bdc4 29
1e71eafb
HWN
30#if (SCM_DEBUG_CELL_ACCESSES == 1)
31#include <stdio.h>
1e71eafb
HWN
32#endif
33
16ea9620
MV
34#include "libguile/pairs.h"
35#include "libguile/gc.h"
9bc4701c 36#include "libguile/threads.h"
9598a406 37#include "libguile/unif.h"
16ea9620 38
c8a1bdc4
HWN
39
40SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
41SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
42 scm_t_bits ccr, scm_t_bits cdr);
43
9598a406
MV
44SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
45SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
16ea9620 46
60e7529a
RB
47
48#if defined SCM_C_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H
49/* either inlining, or being included from inline.c. We use (and
50 repeat) this long #if test here and below so that we don't have to
51 introduce any extraneous symbols into the public namespace. We
52 only need SCM_C_INLINE to be seen publically . */
c8a1bdc4
HWN
53
54extern unsigned scm_newcell2_count;
55extern unsigned scm_newcell_count;
56
60e7529a
RB
57#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
58/* definitely inlining */
2b2c6fca
MV
59#ifdef __GNUC__
60extern
61#else
62static
63#endif
64SCM_C_INLINE
60e7529a 65#endif
c8a1bdc4 66SCM
228a24ef 67scm_cell (scm_t_bits car, scm_t_bits cdr)
16ea9620
MV
68{
69 SCM z;
9bc4701c 70 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
16ea9620 71
d2e53ed6 72 if (scm_is_null (*freelist))
9bc4701c 73 z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
c8a1bdc4 74 else
16ea9620 75 {
9bc4701c
MD
76 z = *freelist;
77 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620 78 }
c8a1bdc4
HWN
79
80 /*
81 We update scm_cells_allocated from this function. If we don't
82 update this explicitly, we will have to walk a freelist somewhere
83 later on, which seems a lot more expensive.
84 */
85 scm_cells_allocated += 1;
86
87#if (SCM_DEBUG_CELL_ACCESSES == 1)
88 if (scm_debug_cell_accesses_p)
1e71eafb
HWN
89 {
90 if (SCM_GC_MARK_P (z))
91 {
92 fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
93 abort();
94 }
6b69393d 95 else if (SCM_GC_CELL_WORD(z, 0) != scm_tc_free_cell)
1e71eafb
HWN
96 {
97 fprintf(stderr, "cell from freelist is not a free cell.\n");
98 abort();
99 }
100 }
101
102 /*
103 Always set mark. Otherwise cells that are alloced before
104 scm_debug_cell_accesses_p is toggled seem invalid.
105 */
106 SCM_SET_GC_MARK (z);
107
108 /*
109 TODO: figure out if this use of mark bits is valid with
110 threading. What if another thread is doing GC at this point
111 ... ?
112 */
c8a1bdc4 113
c8a1bdc4 114#endif
16ea9620 115
c8a1bdc4 116
16ea9620
MV
117 /* Initialize the type slot last so that the cell is ignored by the
118 GC until it is completely initialized. This is only relevant
b2a339f6
MV
119 when the GC can actually run during this code, which it can't
120 since the GC only runs when all other threads are stopped.
16ea9620 121 */
1fc8902f
DH
122 SCM_GC_SET_CELL_WORD (z, 1, cdr);
123 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 124
eab1b259
HWN
125#if (SCM_DEBUG_CELL_ACCESSES == 1)
126 if (scm_expensive_debug_cell_accesses_p )
127 scm_i_expensive_validation_check (z);
128#endif
c8a1bdc4 129
16ea9620
MV
130 return z;
131}
132
60e7529a
RB
133#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
134/* definitely inlining */
2b2c6fca
MV
135#ifdef __GNUC__
136extern
137#else
138static
139#endif
140SCM_C_INLINE
60e7529a 141#endif
c8a1bdc4 142SCM
228a24ef
DH
143scm_double_cell (scm_t_bits car, scm_t_bits cbr,
144 scm_t_bits ccr, scm_t_bits cdr)
16ea9620 145{
5e1e20c8
MV
146 SCM z;
147 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
148
d2e53ed6 149 if (scm_is_null (*freelist))
9bc4701c 150 z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
16ea9620
MV
151 else
152 {
9bc4701c
MD
153 z = *freelist;
154 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620
MV
155 }
156
c8a1bdc4
HWN
157 scm_cells_allocated += 2;
158
16ea9620
MV
159 /* Initialize the type slot last so that the cell is ignored by the
160 GC until it is completely initialized. This is only relevant
b2a339f6
MV
161 when the GC can actually run during this code, which it can't
162 since the GC only runs when all other threads are stopped.
16ea9620 163 */
1fc8902f
DH
164 SCM_GC_SET_CELL_WORD (z, 1, cbr);
165 SCM_GC_SET_CELL_WORD (z, 2, ccr);
166 SCM_GC_SET_CELL_WORD (z, 3, cdr);
167 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 168
c8a1bdc4
HWN
169#if (SCM_DEBUG_CELL_ACCESSES == 1)
170 if (scm_debug_cell_accesses_p)
171 {
172 if (SCM_GC_MARK_P (z))
173 {
174 fprintf(stderr,
175 "scm_double_cell tried to allocate a marked cell.\n");
176 abort();
177 }
c8a1bdc4 178 }
4ad0814a
HWN
179
180 /* see above. */
181 SCM_SET_GC_MARK (z);
182
3553e1d1
GH
183#endif
184
185 /* When this function is inlined, it's possible that the last
186 SCM_GC_SET_CELL_WORD above will be adjacent to a following
187 initialization of z. E.g., it occurred in scm_make_real. GCC
188 from around version 3 (e.g., certainly 3.2) began taking
189 advantage of strict C aliasing rules which say that it's OK to
190 interchange the initialization above and the one below when the
191 pointer types appear to differ sufficiently. We don't want that,
192 of course. GCC allows this behaviour to be disabled with the
193 -fno-strict-aliasing option, but would also need to be supplied
194 by Guile users. Instead, the following statements prevent the
195 reordering.
196 */
197#ifdef __GNUC__
cb975c21 198 __asm__ volatile ("" : : : "memory");
3553e1d1
GH
199#else
200 /* portable version, just in case any other compiler does the same
201 thing. */
202 scm_remember_upto_here_1 (z);
c8a1bdc4 203#endif
6253f3f1 204
c8a1bdc4
HWN
205 return z;
206}
6253f3f1 207
9598a406
MV
208#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
209/* definitely inlining */
210#ifdef __GNUC__
211extern
212#else
213static
214#endif
215SCM_C_INLINE
216#endif
217SCM
218scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
219{
220 return h->ref (h, p);
221}
eab1b259 222
9598a406
MV
223#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
224/* definitely inlining */
225#ifdef __GNUC__
226extern
227#else
228static
229#endif
230SCM_C_INLINE
231#endif
232void
233scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
234{
235 h->set (h, p, v);
236}
eab1b259 237
16ea9620 238#endif
16ea9620 239#endif