6 /* Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
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.
13 * This library 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 GNU
16 * Lesser General Public License for more details.
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
23 /* This file is for inline functions. On platforms that don't support
24 inlining functions, they are turned into ordinary functions. See
28 #include "libguile/__scm.h"
30 #if (SCM_DEBUG_CELL_ACCESSES == 1)
34 #include "libguile/pairs.h"
35 #include "libguile/gc.h"
36 #include "libguile/threads.h"
37 #include "libguile/unif.h"
40 SCM_API SCM
scm_cell (scm_t_bits car
, scm_t_bits cdr
);
41 SCM_API SCM
scm_double_cell (scm_t_bits car
, scm_t_bits cbr
,
42 scm_t_bits ccr
, scm_t_bits cdr
);
44 SCM_API SCM
scm_array_handle_ref (scm_t_array_handle
*h
, ssize_t pos
);
45 SCM_API
void scm_array_handle_set (scm_t_array_handle
*h
, ssize_t pos
, SCM val
);
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 . */
54 extern unsigned scm_newcell2_count
;
55 extern unsigned scm_newcell_count
;
57 #if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
58 /* definitely inlining */
67 scm_cell (scm_t_bits car
, scm_t_bits cdr
)
70 /* We retrieve the SCM pointer only once since the call to
71 SCM_FREELIST_LOC will be slightly expensive when we support
72 preemptive multithreading. SCM_FREELIST_LOC will then retrieve
73 the thread specific freelist.
75 Until then, SCM_FREELIST_DOC expands to (&scm_i_freelist) and the
76 following code will compile to the same as if we had worked
77 directly on the scm_i_freelist variable.
79 SCM
*freelist
= SCM_FREELIST_LOC (scm_i_freelist
);
86 if (scm_is_null (*freelist
))
87 z
= scm_gc_for_newcell (&scm_i_master_freelist
, freelist
);
91 *freelist
= SCM_FREE_CELL_CDR (*freelist
);
95 We update scm_cells_allocated from this function. If we don't
96 update this explicitly, we will have to walk a freelist somewhere
97 later on, which seems a lot more expensive.
99 scm_cells_allocated
+= 1;
101 #if (SCM_DEBUG_CELL_ACCESSES == 1)
102 if (scm_debug_cell_accesses_p
)
104 if (SCM_GC_MARK_P (z
))
106 fprintf(stderr
, "scm_cell tried to allocate a marked cell.\n");
109 else if (SCM_GC_CELL_WORD(z
, 0) != scm_tc_free_cell
)
111 fprintf(stderr
, "cell from freelist is not a free cell.\n");
117 Always set mark. Otherwise cells that are alloced before
118 scm_debug_cell_accesses_p is toggled seem invalid.
123 TODO: figure out if this use of mark bits is valid with
124 threading. What if another thread is doing GC at this point
131 /* Initialize the type slot last so that the cell is ignored by the
132 GC until it is completely initialized. This is only relevant
133 when the GC can actually run during this code, which it can't for
134 cooperating threads, but it might be important when we get true
137 SCM_GC_SET_CELL_WORD (z
, 1, cdr
);
138 SCM_GC_SET_CELL_WORD (z
, 0, car
);
140 #if 0 /*fixme* Hmm... let's consider this later. */
141 #if !defined(SCM_USE_COOP_THREADS) && !defined(SCM_USE_NULL_THREADS) && !defined(SCM_USE_COPT_THREADS)
142 /* When we are using preemtive threads, we might need to make
143 sure that the initial values for the slots are protected until
144 the cell is completely initialized.
147 scm_remember_upto_here_1 (SCM_PACK (cdr
));
151 #if (SCM_DEBUG_CELL_ACCESSES == 1)
152 if (scm_expensive_debug_cell_accesses_p
)
153 scm_i_expensive_validation_check (z
);
159 #if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
160 /* definitely inlining */
169 scm_double_cell (scm_t_bits car
, scm_t_bits cbr
,
170 scm_t_bits ccr
, scm_t_bits cdr
)
173 SCM
*freelist
= SCM_FREELIST_LOC (scm_i_freelist2
);
175 if (scm_gc_running_p
)
180 if (scm_is_null (*freelist
))
181 z
= scm_gc_for_newcell (&scm_i_master_freelist2
, freelist
);
185 *freelist
= SCM_FREE_CELL_CDR (*freelist
);
188 scm_cells_allocated
+= 2;
190 /* Initialize the type slot last so that the cell is ignored by the
191 GC until it is completely initialized. This is only relevant
192 when the GC can actually run during this code, which it can't for
193 cooperating threads, but it might be important when we get true
196 SCM_GC_SET_CELL_WORD (z
, 1, cbr
);
197 SCM_GC_SET_CELL_WORD (z
, 2, ccr
);
198 SCM_GC_SET_CELL_WORD (z
, 3, cdr
);
199 SCM_GC_SET_CELL_WORD (z
, 0, car
);
201 #if 0 /*fixme* Hmm... let's consider this later. */
202 #if !defined(SCM_USE_COOP_THREADS) && !defined(SCM_USE_NULL_THREADS) && !defined(SCM_USE_COPT_THREADS)
203 /* When we are using non-cooperating threads, we might need to make
204 sure that the initial values for the slots are protected until
205 the cell is completely initialized.
208 scm_remember_upto_here_3 (SCM_PACK (cbr
), SCM_PACK (ccr
), SCM_PACK (cdr
));
213 #if (SCM_DEBUG_CELL_ACCESSES == 1)
214 if (scm_debug_cell_accesses_p
)
216 if (SCM_GC_MARK_P (z
))
219 "scm_double_cell tried to allocate a marked cell.\n");
229 /* When this function is inlined, it's possible that the last
230 SCM_GC_SET_CELL_WORD above will be adjacent to a following
231 initialization of z. E.g., it occurred in scm_make_real. GCC
232 from around version 3 (e.g., certainly 3.2) began taking
233 advantage of strict C aliasing rules which say that it's OK to
234 interchange the initialization above and the one below when the
235 pointer types appear to differ sufficiently. We don't want that,
236 of course. GCC allows this behaviour to be disabled with the
237 -fno-strict-aliasing option, but would also need to be supplied
238 by Guile users. Instead, the following statements prevent the
242 asm volatile ("" : : : "memory");
244 /* portable version, just in case any other compiler does the same
246 scm_remember_upto_here_1 (z
);
252 #if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
253 /* definitely inlining */
262 scm_array_handle_ref (scm_t_array_handle
*h
, ssize_t p
)
264 return h
->ref (h
, p
);
267 #if defined SCM_C_INLINE && ! defined SCM_INLINE_C_INCLUDING_INLINE_H
268 /* definitely inlining */
277 scm_array_handle_set (scm_t_array_handle
*h
, ssize_t p
, SCM v
)