* __scm.h (SCM_ALLOW_INTS_ONLY): Removed.
[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
b1e945d7 6/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
16ea9620
MV
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this software; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 * Boston, MA 02111-1307 USA
22 *
23 * As a special exception, the Free Software Foundation gives permission
24 * for additional uses of the text contained in its release of GUILE.
25 *
26 * The exception is that, if you link the GUILE library with other files
27 * to produce an executable, this does not by itself cause the
28 * resulting executable to be covered by the GNU General Public License.
29 * Your use of that executable is in no way restricted on account of
30 * linking the GUILE library code into it.
31 *
32 * This exception does not however invalidate any other reasons why
33 * the executable file might be covered by the GNU General Public License.
34 *
35 * This exception applies only to the code released by the
36 * Free Software Foundation under the name GUILE. If you copy
37 * code from other Free Software Foundation releases into a copy of
38 * GUILE, as the General Public License permits, the exception does
39 * not apply to the code that you add in this way. To avoid misleading
40 * anyone as to the status of such modified files, you must delete
41 * this exception notice from them.
42 *
43 * If you write modifications of your own for GUILE, it is your choice
44 * whether to permit this exception to apply to your modifications.
45 * If you do not wish that, delete this exception notice. */
46
47/* This file is for inline functions. On platforms that don't support
48 inlining functions, they are turned into ordinary functions. See
49 "inline.c".
50*/
51
c8a1bdc4 52
1e71eafb
HWN
53#if (SCM_DEBUG_CELL_ACCESSES == 1)
54#include <stdio.h>
55
56#endif
57
16ea9620
MV
58#include "libguile/pairs.h"
59#include "libguile/gc.h"
9bc4701c 60#include "libguile/threads.h"
16ea9620 61
c8a1bdc4
HWN
62
63SCM_API SCM scm_cell (scm_t_bits car, scm_t_bits cdr);
64SCM_API SCM scm_double_cell (scm_t_bits car, scm_t_bits cbr,
65 scm_t_bits ccr, scm_t_bits cdr);
66
16ea9620
MV
67#ifdef HAVE_INLINE
68
c8a1bdc4
HWN
69#ifndef EXTERN_INLINE
70#define EXTERN_INLINE extern inline
71#endif
72
73extern unsigned scm_newcell2_count;
74extern unsigned scm_newcell_count;
75
76
eab1b259 77
c8a1bdc4
HWN
78EXTERN_INLINE
79SCM
228a24ef 80scm_cell (scm_t_bits car, scm_t_bits cdr)
16ea9620
MV
81{
82 SCM z;
9bc4701c
MD
83 /* We retrieve the SCM pointer only once since the call to
84 SCM_FREELIST_LOC will be slightly expensive when we support
85 preemptive multithreading. SCM_FREELIST_DOC will then retrieve
86 the thread specific freelist.
87
88 Until then, SCM_FREELIST_DOC expands to (&scm_i_freelist) and the
89 following code will compile to the same as if we had worked
90 directly on the scm_i_freelist variable.
91 */
92 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist);
16ea9620 93
9bc4701c
MD
94 if (SCM_NULLP (*freelist))
95 z = scm_gc_for_newcell (&scm_i_master_freelist, freelist);
c8a1bdc4 96 else
16ea9620 97 {
9bc4701c
MD
98 z = *freelist;
99 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620 100 }
c8a1bdc4
HWN
101
102 /*
103 We update scm_cells_allocated from this function. If we don't
104 update this explicitly, we will have to walk a freelist somewhere
105 later on, which seems a lot more expensive.
106 */
107 scm_cells_allocated += 1;
108
109#if (SCM_DEBUG_CELL_ACCESSES == 1)
110 if (scm_debug_cell_accesses_p)
1e71eafb
HWN
111 {
112 if (SCM_GC_MARK_P (z))
113 {
114 fprintf(stderr, "scm_cell tried to allocate a marked cell.\n");
115 abort();
116 }
117 else if (SCM_GC_CELL_TYPE(z) != scm_tc_free_cell)
118 {
119 fprintf(stderr, "cell from freelist is not a free cell.\n");
120 abort();
121 }
122 }
123
124 /*
125 Always set mark. Otherwise cells that are alloced before
126 scm_debug_cell_accesses_p is toggled seem invalid.
127 */
128 SCM_SET_GC_MARK (z);
129
130 /*
131 TODO: figure out if this use of mark bits is valid with
132 threading. What if another thread is doing GC at this point
133 ... ?
134 */
c8a1bdc4 135
c8a1bdc4 136#endif
16ea9620 137
c8a1bdc4 138
16ea9620
MV
139 /* Initialize the type slot last so that the cell is ignored by the
140 GC until it is completely initialized. This is only relevant
141 when the GC can actually run during this code, which it can't for
142 cooperating threads, but it might be important when we get true
143 preemptive threads.
144 */
1fc8902f
DH
145 SCM_GC_SET_CELL_WORD (z, 1, cdr);
146 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 147
9bc4701c 148#if 0 /*fixme* Hmm... let's consider this later. */
b1e945d7 149#if !defined(USE_COOP_THREADS) && !defined(USE_NULL_THREADS) && !defined(USE_COPT_THREADS)
389626c5 150 /* When we are using preemtive threads, we might need to make
16ea9620
MV
151 sure that the initial values for the slots are protected until
152 the cell is completely initialized.
153 */
154#error review me
155 scm_remember_upto_here_1 (SCM_PACK (cdr));
156#endif
9bc4701c 157#endif
c8a1bdc4 158
eab1b259
HWN
159#if (SCM_DEBUG_CELL_ACCESSES == 1)
160 if (scm_expensive_debug_cell_accesses_p )
161 scm_i_expensive_validation_check (z);
162#endif
c8a1bdc4 163
16ea9620
MV
164 return z;
165}
166
c8a1bdc4
HWN
167EXTERN_INLINE
168SCM
228a24ef
DH
169scm_double_cell (scm_t_bits car, scm_t_bits cbr,
170 scm_t_bits ccr, scm_t_bits cdr)
16ea9620
MV
171{
172 SCM z;
9bc4701c 173 SCM *freelist = SCM_FREELIST_LOC (scm_i_freelist2);
16ea9620 174
9bc4701c
MD
175 if (SCM_NULLP (*freelist))
176 z = scm_gc_for_newcell (&scm_i_master_freelist2, freelist);
16ea9620
MV
177 else
178 {
9bc4701c
MD
179 z = *freelist;
180 *freelist = SCM_FREE_CELL_CDR (*freelist);
16ea9620
MV
181 }
182
c8a1bdc4
HWN
183 scm_cells_allocated += 2;
184
16ea9620
MV
185 /* Initialize the type slot last so that the cell is ignored by the
186 GC until it is completely initialized. This is only relevant
187 when the GC can actually run during this code, which it can't for
188 cooperating threads, but it might be important when we get true
189 preemptive threads.
190 */
1fc8902f
DH
191 SCM_GC_SET_CELL_WORD (z, 1, cbr);
192 SCM_GC_SET_CELL_WORD (z, 2, ccr);
193 SCM_GC_SET_CELL_WORD (z, 3, cdr);
194 SCM_GC_SET_CELL_WORD (z, 0, car);
16ea9620 195
9bc4701c 196#if 0 /*fixme* Hmm... let's consider this later. */
b1e945d7 197#if !defined(USE_COOP_THREADS) && !defined(USE_NULL_THREADS) && !defined(USE_COPT_THREADS)
16ea9620
MV
198 /* When we are using non-cooperating threads, we might need to make
199 sure that the initial values for the slots are protected until
200 the cell is completely initialized.
201 */
202#error review me
203 scm_remember_upto_here_3 (SCM_PACK (cbr), SCM_PACK (ccr), SCM_PACK (cdr));
204#endif
9bc4701c 205#endif
16ea9620 206
16ea9620 207
c8a1bdc4
HWN
208#if (SCM_DEBUG_CELL_ACCESSES == 1)
209 if (scm_debug_cell_accesses_p)
210 {
211 if (SCM_GC_MARK_P (z))
212 {
213 fprintf(stderr,
214 "scm_double_cell tried to allocate a marked cell.\n");
215 abort();
216 }
c8a1bdc4 217 }
4ad0814a
HWN
218
219 /* see above. */
220 SCM_SET_GC_MARK (z);
221
3553e1d1
GH
222#endif
223
224 /* When this function is inlined, it's possible that the last
225 SCM_GC_SET_CELL_WORD above will be adjacent to a following
226 initialization of z. E.g., it occurred in scm_make_real. GCC
227 from around version 3 (e.g., certainly 3.2) began taking
228 advantage of strict C aliasing rules which say that it's OK to
229 interchange the initialization above and the one below when the
230 pointer types appear to differ sufficiently. We don't want that,
231 of course. GCC allows this behaviour to be disabled with the
232 -fno-strict-aliasing option, but would also need to be supplied
233 by Guile users. Instead, the following statements prevent the
234 reordering.
235 */
236#ifdef __GNUC__
237 asm volatile ("" : : : "memory");
238#else
239 /* portable version, just in case any other compiler does the same
240 thing. */
241 scm_remember_upto_here_1 (z);
c8a1bdc4 242#endif
6253f3f1 243
c8a1bdc4
HWN
244 return z;
245}
6253f3f1 246
eab1b259
HWN
247
248
16ea9620 249#endif
16ea9620 250#endif