3 #ifndef SCM_GC_INLINE_H
4 #define SCM_GC_INLINE_H
6 /* Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
7 * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 /* Much of this file was copied from gc_inline.h, from the BDW
26 * collector. Its copyright notice is:
28 * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
29 * Copyright (c) 1991-1995 by Xerox Corporation. All rights reserved.
30 * Copyright (c) 2005 Hewlett-Packard Development Company, L.P.
32 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
33 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
35 * Permission is hereby granted to use or copy this program
36 * for any purpose, provided the above notices are retained on all copies.
37 * Permission to modify the code and to distribute modified code is granted,
38 * provided the above notices are retained, and a notice that the code was
39 * modified is included with the above copyright notice.
44 #include "libguile/__scm.h"
46 #include "libguile/gc.h"
47 #include "libguile/bdw-gc.h"
48 #include "libguile/threads.h"
50 #include <gc/gc_inline.h> /* GC_generic_malloc_many */
54 #define SCM_INLINE_GC_GRANULE_WORDS 2
55 #define SCM_INLINE_GC_GRANULE_BYTES \
56 (sizeof(void *) * SCM_INLINE_GC_GRANULE_WORDS)
58 /* A freelist set contains SCM_INLINE_GC_FREELIST_COUNT pointers to
59 singly linked lists of objects of different sizes, the ith one
60 containing objects i + 1 granules in size. This setting of
61 SCM_INLINE_GC_FREELIST_COUNT will hold freelists for allocations of
63 #define SCM_INLINE_GC_FREELIST_COUNT (256U / SCM_INLINE_GC_GRANULE_BYTES)
66 scm_inline_gc_bytes_to_freelist_index (size_t bytes
)
68 return (bytes
- 1U) / SCM_INLINE_GC_GRANULE_BYTES
;
72 scm_inline_gc_freelist_object_size (size_t idx
)
74 return (idx
+ 1U) * SCM_INLINE_GC_GRANULE_BYTES
;
77 /* The values of these must match the internal POINTERLESS and NORMAL
78 definitions in libgc, for which unfortunately there are no external
79 definitions. Alack. */
80 typedef enum scm_inline_gc_kind
82 SCM_INLINE_GC_KIND_POINTERLESS
,
83 SCM_INLINE_GC_KIND_NORMAL
87 scm_inline_gc_alloc (void **freelist
, size_t idx
, scm_inline_gc_kind kind
)
89 void *head
= *freelist
;
91 if (SCM_UNLIKELY (!head
))
93 size_t bytes
= scm_inline_gc_freelist_object_size (idx
);
94 GC_generic_malloc_many (bytes
, kind
, freelist
);
96 if (SCM_UNLIKELY (!head
))
97 return (*GC_get_oom_fn ()) (bytes
);
100 *freelist
= *(void **)(head
);
106 scm_inline_gc_malloc_pointerless (scm_i_thread
*thread
, size_t bytes
)
108 size_t idx
= scm_inline_gc_bytes_to_freelist_index (bytes
);
110 if (SCM_UNLIKELY (idx
>= SCM_INLINE_GC_FREELIST_COUNT
))
111 return GC_malloc_atomic (bytes
);
113 return scm_inline_gc_alloc
114 (&thread
->pointerless_freelists
[idx
], idx
, SCM_INLINE_GC_KIND_POINTERLESS
);
118 scm_inline_gc_malloc (scm_i_thread
*thread
, size_t bytes
)
120 size_t idx
= scm_inline_gc_bytes_to_freelist_index (bytes
);
122 if (SCM_UNLIKELY (idx
>= SCM_INLINE_GC_FREELIST_COUNT
))
123 return GC_malloc (bytes
);
125 return scm_inline_gc_alloc
126 (&thread
->freelists
[idx
], idx
, SCM_INLINE_GC_KIND_NORMAL
);
130 scm_inline_gc_malloc_words (scm_i_thread
*thread
, size_t words
)
132 return scm_inline_gc_malloc (thread
, words
* sizeof (void *));
136 scm_inline_cell (scm_i_thread
*thread
, scm_t_bits car
, scm_t_bits cdr
)
138 SCM cell
= SCM_PACK_POINTER (scm_inline_gc_malloc_words (thread
, 2));
140 SCM_GC_SET_CELL_WORD (cell
, 0, car
);
141 SCM_GC_SET_CELL_WORD (cell
, 1, cdr
);
147 scm_inline_double_cell (scm_i_thread
*thread
, scm_t_bits car
, scm_t_bits cbr
,
148 scm_t_bits ccr
, scm_t_bits cdr
)
150 SCM cell
= SCM_PACK_POINTER (scm_inline_gc_malloc_words (thread
, 4));
152 SCM_GC_SET_CELL_WORD (cell
, 0, car
);
153 SCM_GC_SET_CELL_WORD (cell
, 1, cbr
);
154 SCM_GC_SET_CELL_WORD (cell
, 2, ccr
);
155 SCM_GC_SET_CELL_WORD (cell
, 3, cdr
);
161 scm_inline_words (scm_i_thread
*thread
, scm_t_bits car
, scm_t_uint32 n_words
)
163 SCM obj
= SCM_PACK_POINTER (scm_inline_gc_malloc_words (thread
, n_words
));
165 SCM_GC_SET_CELL_WORD (obj
, 0, car
);
171 scm_inline_cons (scm_i_thread
*thread
, SCM x
, SCM y
)
173 return scm_inline_cell (thread
, SCM_UNPACK (x
), SCM_UNPACK (y
));
177 #endif /* SCM_GC_INLINE_H */