2006-02-01 Ludovic Courtès <ludovic.courtes@laas.fr>
[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
92205699 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
73be1d9e 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"
d5ad4aa6 38#include "libguile/pairs.h"
16ea9620 39
c8a1bdc4
HWN
40
41SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
42SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
43 scm_t_bits ccr, scm_t_bits cdr);
44
9598a406
MV
45SCM_API SCM scm_array_handle_ref (scm_t_array_handle *h, ssize_t pos);
46SCM_API void scm_array_handle_set (scm_t_array_handle *h, ssize_t pos, SCM val);
16ea9620 47
60e7529a
RB
48
49#if defined SCM_C_INLINE || defined SCM_INLINE_C_INCLUDING_INLINE_H
50/* either inlining, or being included from inline.c. We use (and
51 repeat) this long #if test here and below so that we don't have to
52 introduce any extraneous symbols into the public namespace. We
53 only need SCM_C_INLINE to be seen publically . */
c8a1bdc4
HWN
54
55extern unsigned scm_newcell2_count;
56extern unsigned scm_newcell_count;
57
60e7529a
RB
58#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
59/* definitely inlining */
2b2c6fca
MV
60#ifdef __GNUC__
61extern
62#else
63static
64#endif
65SCM_C_INLINE
60e7529a 66#endif
c8a1bdc4 67SCM
228a24ef 68scm_cell (scm_t_bits car, scm_t_bits cdr)
16ea9620
MV
69{
70 SCM z;
9bc4701c 71 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
16ea9620 72
d2e53ed6 73 if (scm_is_null (*freelist))
9bc4701c 74 z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
c8a1bdc4 75 else
16ea9620 76 {
9bc4701c
MD
77 z = *freelist;
78 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620 79 }
c8a1bdc4
HWN
80
81 /*
82 We update scm_cells_allocated from this function. If we don't
83 update this explicitly, we will have to walk a freelist somewhere
84 later on, which seems a lot more expensive.
85 */
86 scm_cells_allocated += 1;
87
88#if (SCM_DEBUG_CELL_ACCESSES == 1)
89 if (scm_debug_cell_accesses_p)
1e71eafb
HWN
90 {
91 if (SCM_GC_MARK_P (z))
92 {
93 fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
94 abort();
95 }
6b69393d 96 else if (SCM_GC_CELL_WORD(z, 0) != scm_tc_free_cell)
1e71eafb
HWN
97 {
98 fprintf(stderr, "cell from freelist is not a free cell.\n");
99 abort();
100 }
101 }
102
103 /*
104 Always set mark. Otherwise cells that are alloced before
105 scm_debug_cell_accesses_p is toggled seem invalid.
106 */
107 SCM_SET_GC_MARK (z);
108
109 /*
110 TODO: figure out if this use of mark bits is valid with
111 threading. What if another thread is doing GC at this point
112 ... ?
113 */
c8a1bdc4 114
c8a1bdc4 115#endif
16ea9620 116
c8a1bdc4 117
16ea9620
MV
118 /* Initialize the type slot last so that the cell is ignored by the
119 GC until it is completely initialized. This is only relevant
b2a339f6
MV
120 when the GC can actually run during this code, which it can't
121 since the GC only runs when all other threads are stopped.
16ea9620 122 */
1fc8902f
DH
123 SCM_GC_SET_CELL_WORD (z, 1, cdr);
124 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 125
eab1b259
HWN
126#if (SCM_DEBUG_CELL_ACCESSES == 1)
127 if (scm_expensive_debug_cell_accesses_p )
128 scm_i_expensive_validation_check (z);
129#endif
c8a1bdc4 130
16ea9620
MV
131 return z;
132}
133
60e7529a
RB
134#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
135/* definitely inlining */
2b2c6fca
MV
136#ifdef __GNUC__
137extern
138#else
139static
140#endif
141SCM_C_INLINE
60e7529a 142#endif
c8a1bdc4 143SCM
228a24ef
DH
144scm_double_cell (scm_t_bits car, scm_t_bits cbr,
145 scm_t_bits ccr, scm_t_bits cdr)
16ea9620 146{
5e1e20c8
MV
147 SCM z;
148 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
149
d2e53ed6 150 if (scm_is_null (*freelist))
9bc4701c 151 z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
16ea9620
MV
152 else
153 {
9bc4701c
MD
154 z = *freelist;
155 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620
MV
156 }
157
c8a1bdc4
HWN
158 scm_cells_allocated += 2;
159
16ea9620
MV
160 /* Initialize the type slot last so that the cell is ignored by the
161 GC until it is completely initialized. This is only relevant
b2a339f6
MV
162 when the GC can actually run during this code, which it can't
163 since the GC only runs when all other threads are stopped.
16ea9620 164 */
1fc8902f
DH
165 SCM_GC_SET_CELL_WORD (z, 1, cbr);
166 SCM_GC_SET_CELL_WORD (z, 2, ccr);
167 SCM_GC_SET_CELL_WORD (z, 3, cdr);
168 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 169
c8a1bdc4
HWN
170#if (SCM_DEBUG_CELL_ACCESSES == 1)
171 if (scm_debug_cell_accesses_p)
172 {
173 if (SCM_GC_MARK_P (z))
174 {
175 fprintf(stderr,
176 "scm_double_cell tried to allocate a marked cell.\n");
177 abort();
178 }
c8a1bdc4 179 }
4ad0814a
HWN
180
181 /* see above. */
182 SCM_SET_GC_MARK (z);
183
3553e1d1
GH
184#endif
185
186 /* When this function is inlined, it's possible that the last
187 SCM_GC_SET_CELL_WORD above will be adjacent to a following
188 initialization of z. E.g., it occurred in scm_make_real. GCC
189 from around version 3 (e.g., certainly 3.2) began taking
190 advantage of strict C aliasing rules which say that it's OK to
191 interchange the initialization above and the one below when the
192 pointer types appear to differ sufficiently. We don't want that,
193 of course. GCC allows this behaviour to be disabled with the
194 -fno-strict-aliasing option, but would also need to be supplied
195 by Guile users. Instead, the following statements prevent the
196 reordering.
197 */
198#ifdef __GNUC__
cb975c21 199 __asm__ volatile ("" : : : "memory");
3553e1d1
GH
200#else
201 /* portable version, just in case any other compiler does the same
202 thing. */
203 scm_remember_upto_here_1 (z);
c8a1bdc4 204#endif
6253f3f1 205
c8a1bdc4
HWN
206 return z;
207}
6253f3f1 208
9598a406
MV
209#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
210/* definitely inlining */
211#ifdef __GNUC__
212extern
213#else
214static
215#endif
216SCM_C_INLINE
217#endif
218SCM
219scm_array_handle_ref (scm_t_array_handle *h, ssize_t p)
220{
221 return h->ref (h, p);
222}
eab1b259 223
9598a406
MV
224#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
225/* definitely inlining */
226#ifdef __GNUC__
227extern
228#else
229static
230#endif
231SCM_C_INLINE
232#endif
233void
234scm_array_handle_set (scm_t_array_handle *h, ssize_t p, SCM v)
235{
236 h->set (h, p, v);
237}
eab1b259 238
d5ad4aa6
MV
239#if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
240/* definitely inlining */
241#ifdef __GNUC__
242extern
243#else
244static
245#endif
246SCM_C_INLINE
247#endif
248int
249scm_is_pair (SCM x)
250{
251 return SCM_I_CONSP (x);
252}
253
16ea9620 254#endif
16ea9620 255#endif