1 /* -*-C-*-
2 
3 Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
4     1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5     2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Massachusetts
6     Institute of Technology
7 
8 This file is part of MIT/GNU Scheme.
9 
10 MIT/GNU Scheme is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or (at
13 your option) any later version.
14 
15 MIT/GNU Scheme is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with MIT/GNU Scheme; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
23 USA.
24 
25 */
26 
27 /* This file contains the macros for use in code which does GC-like
28    loops over memory.  It is only included in a few files, unlike
29    gc.h which contains general purpose macros and constants. */
30 
31 #ifndef SCM_GCCODE_H
32 #define SCM_GCCODE_H 1
33 
34 #include "gc.h"
35 #include "cmpgc.h"
36 #include "fasl.h"
37 
38 #ifdef ENABLE_DEBUGGING_TOOLS
39 #  ifndef ENABLE_GC_DEBUGGING_TOOLS
40 #    define ENABLE_GC_DEBUGGING_TOOLS
41 #  endif
42 #endif
43 
44 typedef SCHEME_OBJECT * gc_handler_t
45   (SCHEME_OBJECT *, SCHEME_OBJECT);
46 
47 #define DEFINE_GC_HANDLER(handler_name)					\
48 SCHEME_OBJECT *								\
49 handler_name (SCHEME_OBJECT * scan, SCHEME_OBJECT object)
50 
51 typedef SCHEME_OBJECT gc_tuple_handler_t
52   (SCHEME_OBJECT, unsigned int);
53 
54 #define DEFINE_GC_TUPLE_HANDLER(handler_name)				\
55 SCHEME_OBJECT								\
56 handler_name (SCHEME_OBJECT tuple, unsigned int n_words)
57 
58 typedef SCHEME_OBJECT gc_vector_handler_t
59   (SCHEME_OBJECT, bool);
60 
61 #define DEFINE_GC_VECTOR_HANDLER(handler_name)				\
62 SCHEME_OBJECT								\
63 handler_name (SCHEME_OBJECT vector, bool align_p)
64 
65 typedef SCHEME_OBJECT gc_object_handler_t
66   (SCHEME_OBJECT);
67 
68 #define DEFINE_GC_OBJECT_HANDLER(handler_name)				\
69 SCHEME_OBJECT								\
70 handler_name (SCHEME_OBJECT object)
71 
72 typedef SCHEME_OBJECT * gc_precheck_from_t (SCHEME_OBJECT *);
73 
74 #define DEFINE_GC_PRECHECK_FROM(handler_name)				\
75 SCHEME_OBJECT *								\
76 handler_name (SCHEME_OBJECT * from)
77 
78 typedef SCHEME_OBJECT * gc_transport_words_t
79   (SCHEME_OBJECT *, unsigned long, bool);
80 
81 #define DEFINE_GC_TRANSPORT_WORDS(handler_name)				\
82 SCHEME_OBJECT *								\
83 handler_name (SCHEME_OBJECT * from, unsigned long n_words, bool align_p)
84 
85 typedef bool gc_ignore_object_p_t (SCHEME_OBJECT);
86 
87 #define DEFINE_GC_IGNORE_OBJECT_P(handler_name)				\
88 bool									\
89 handler_name (SCHEME_OBJECT object)
90 
91 typedef SCHEME_OBJECT gc_raw_address_to_object_t
92   (unsigned int, SCHEME_OBJECT *);
93 typedef SCHEME_OBJECT * gc_object_to_raw_address_t (SCHEME_OBJECT);
94 typedef SCHEME_OBJECT gc_raw_address_to_cc_entry_t (insn_t *);
95 typedef insn_t * gc_cc_entry_to_raw_address_t (SCHEME_OBJECT);
96 
97 typedef struct
98 {
99   gc_handler_t * handlers [N_TYPE_CODES];
100   gc_tuple_handler_t * tuple_handler;
101   gc_vector_handler_t * vector_handler;
102   gc_object_handler_t * cc_entry_handler;
103   gc_precheck_from_t * precheck_from;
104   gc_transport_words_t * transport_words;
105   gc_ignore_object_p_t * ignore_object_p;
106   gc_raw_address_to_object_t * raw_address_to_object;
107   gc_object_to_raw_address_t * object_to_raw_address;
108   gc_raw_address_to_cc_entry_t * raw_address_to_cc_entry;
109   gc_cc_entry_to_raw_address_t * cc_entry_to_raw_address;
110 } gc_table_t;
111 
112 #define GCT_ENTRY(table, type) (((table)->handlers) [(type)])
113 #define GCT_TUPLE(table) ((table)->tuple_handler)
114 #define GCT_VECTOR(table) ((table)->vector_handler)
115 #define GCT_CC_ENTRY(table) ((table)->cc_entry_handler)
116 #define GCT_PRECHECK_FROM(table) ((table)->precheck_from)
117 #define GCT_TRANSPORT_WORDS(table) ((table)->transport_words)
118 #define GCT_IGNORE_OBJECT_P(table) ((table)->ignore_object_p)
119 #define GCT_RAW_ADDRESS_TO_OBJECT(table) ((table)->raw_address_to_object)
120 #define GCT_OBJECT_TO_RAW_ADDRESS(table) ((table)->object_to_raw_address)
121 #define GCT_RAW_ADDRESS_TO_CC_ENTRY(table) ((table)->raw_address_to_cc_entry)
122 #define GCT_CC_ENTRY_TO_RAW_ADDRESS(table) ((table)->cc_entry_to_raw_address)
123 
124 #define GC_HANDLE_TUPLE(object, n_words)				\
125   ((* (GCT_TUPLE (current_gc_table))) ((object), (n_words)))
126 
127 #define GC_HANDLE_VECTOR(object, align_p)				\
128   ((* (GCT_VECTOR (current_gc_table))) ((object), (align_p)))
129 
130 #define GC_HANDLE_CC_ENTRY(object)					\
131   ((* (GCT_CC_ENTRY (current_gc_table))) (object))
132 
133 #define GC_PRECHECK_FROM(from)						\
134   ((* (GCT_PRECHECK_FROM (current_gc_table))) (from))
135 
136 #define GC_TRANSPORT_WORDS(from, n_words, align_p)			\
137   ((* (GCT_TRANSPORT_WORDS (current_gc_table))) ((from), (n_words), (align_p)))
138 
139 #define GC_RAW_ADDRESS_TO_OBJECT(type, addr)				\
140   ((* (GCT_RAW_ADDRESS_TO_OBJECT (current_gc_table))) ((type), (addr)))
141 
142 #define GC_OBJECT_TO_RAW_ADDRESS(object)				\
143   ((* (GCT_OBJECT_TO_RAW_ADDRESS (current_gc_table))) (object))
144 
145 #define GC_RAW_ADDRESS_TO_CC_ENTRY(addr)				\
146   ((* (GCT_RAW_ADDRESS_TO_CC_ENTRY (current_gc_table))) (addr))
147 
148 #define GC_CC_ENTRY_TO_RAW_ADDRESS(object)				\
149   ((* (GCT_CC_ENTRY_TO_RAW_ADDRESS (current_gc_table))) (object))
150 
151 extern gc_table_t * current_gc_table;
152 
153 extern gc_handler_t gc_handle_non_pointer;
154 extern gc_handler_t gc_handle_cell;
155 extern gc_handler_t gc_handle_pair;
156 extern gc_handler_t gc_handle_triple;
157 extern gc_handler_t gc_handle_quadruple;
158 extern gc_handler_t gc_handle_weak_pair;
159 extern gc_handler_t gc_handle_ephemeron;
160 extern gc_handler_t gc_handle_cc_entry;
161 extern gc_handler_t gc_handle_aligned_vector;
162 extern gc_handler_t gc_handle_unaligned_vector;
163 extern gc_handler_t gc_handle_broken_heart;
164 extern gc_handler_t gc_handle_nmv;
165 extern gc_handler_t gc_handle_reference_trap;
166 extern gc_handler_t gc_handle_linkage_section;
167 extern gc_handler_t gc_handle_manifest_closure;
168 extern gc_handler_t gc_handle_undefined;
169 
170 extern gc_tuple_handler_t gc_tuple;
171 extern gc_vector_handler_t gc_vector;
172 extern gc_object_handler_t gc_cc_entry;
173 extern gc_precheck_from_t gc_precheck_from;
174 extern gc_precheck_from_t gc_precheck_from_no_transport;
175 extern gc_transport_words_t gc_transport_words;
176 extern gc_transport_words_t gc_no_transport_words;
177 extern gc_raw_address_to_object_t gc_raw_address_to_object;
178 extern gc_object_to_raw_address_t gc_object_to_raw_address;
179 extern gc_raw_address_to_cc_entry_t gc_raw_address_to_cc_entry;
180 extern gc_cc_entry_to_raw_address_t gc_cc_entry_to_raw_address;
181 
182 extern void initialize_gc_table (gc_table_t *, bool);
183 
184 typedef void gc_tospace_allocator_t
185   (unsigned long, SCHEME_OBJECT **, SCHEME_OBJECT **);
186 typedef void gc_abort_handler_t (void);
187 typedef bool gc_walk_proc_t (SCHEME_OBJECT *, SCHEME_OBJECT *, void *);
188 
189 extern void initialize_gc
190   (unsigned long, SCHEME_OBJECT **, SCHEME_OBJECT **,
191    gc_tospace_allocator_t *, gc_abort_handler_t * NORETURN);
192 
193 extern void resize_tospace (unsigned long);
194 extern void open_tospace (SCHEME_OBJECT *);
195 extern bool tospace_available_p (unsigned long);
196 extern void add_to_tospace (SCHEME_OBJECT);
197 extern SCHEME_OBJECT read_tospace (SCHEME_OBJECT *);
198 extern void write_tospace (SCHEME_OBJECT *, SCHEME_OBJECT);
199 extern void increment_tospace_ptr (unsigned long);
200 extern SCHEME_OBJECT * get_newspace_ptr (void);
201 extern void * tospace_to_newspace (void *);
202 extern void * newspace_to_tospace (void *);
203 extern bool save_tospace (gc_walk_proc_t *, void *);
204 extern void discard_tospace (void);
205 
206 extern void initialize_weak_chain (void);
207 extern void update_weak_pointers (void);
208 
209 extern gc_table_t * std_gc_table (void);
210 extern void gc_scan_oldspace (SCHEME_OBJECT *, SCHEME_OBJECT *);
211 extern void gc_scan_tospace (SCHEME_OBJECT *, SCHEME_OBJECT *);
212 
213 extern void std_gc_death (const char *, ...)
214   ATTRIBUTE ((__noreturn__, __format__ (__printf__, 1, 2)));
215 extern void gc_no_cc_support (void) NORETURN;
216 extern void gc_bad_type (SCHEME_OBJECT) NORETURN;
217 
218 #ifdef ENABLE_GC_DEBUGGING_TOOLS
219    extern void collect_gc_object_references (SCHEME_OBJECT, SCHEME_OBJECT);
220    extern void initialize_gc_object_references (void);
221    extern void finalize_gc_object_references (void);
222 #endif
223 
224 #endif /* not SCM_GCCODE_H */
225