[sgen] More client interface documentation.
[mono.git] / mono / metadata / sgen-client.h
1 /*
2  * sgen-client.h: SGen client interface.
3  *
4  * Copyright (C) 2014 Xamarin Inc
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License 2.0 as published by the Free Software Foundation;
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License 2.0 along with this library; if not, write to the Free
17  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 #include "mono/metadata/sgen-pointer-queue.h"
21
22 /*
23  * Init whatever needs initing.  This is called relatively early in SGen initialization.
24  * Must initialized the small ID for the current thread.
25  */
26 void sgen_client_init (void);
27
28 /*
29  * The slow path for getting an object's size.  We're passing in the vtable because we've
30  * already fetched it.
31  */
32 mword sgen_client_slow_object_get_size (GCVTable *vtable, GCObject* o);
33
34 /*
35  * Fill the given range with a dummy object.  If the range is too short to be filled with an
36  * object, null it.  Return `TRUE` if the range was filled with an object, `FALSE` if it was
37  * nulled.
38  */
39 gboolean sgen_client_array_fill_range (char *start, size_t size);
40
41 /*
42  * This is called if the nursery clearing policy at `clear-at-gc`, which is usually only
43  * used for debugging.  If `size` is large enough for the memory to have been filled with a
44  * dummy, object, zero its header.  Note that there might not actually be a header there.
45  */
46 void sgen_client_zero_array_fill_header (void *p, size_t size);
47
48 /*
49  * Return whether the given object is an array fill dummy object.
50  */
51 gboolean sgen_client_object_is_array_fill (GCObject *o);
52
53 /*
54  * Return whether the given finalizable object's finalizer is critical, i.e., needs to run
55  * after all non-critical finalizers have run.
56  */
57 gboolean sgen_client_object_has_critical_finalizer (GCObject *obj);
58
59 /*
60  * Called after an object is enqueued for finalization.  This is a very low-level callback.
61  * It should almost certainly be a NOP.
62  *
63  * FIXME: Can we merge this with `sgen_client_object_has_critical_finalizer()`?
64  */
65 void sgen_client_object_queued_for_finalization (GCObject *obj);
66
67 /*
68  * Run the given object's finalizer.
69  */
70 void sgen_client_run_finalize (GCObject *obj);
71
72 /*
73  * Is called after a collection if there are objects to finalize.  The world is still
74  * stopped.  This will usually notify the finalizer thread that it needs to run.
75  */
76 void sgen_client_finalize_notify (void);
77
78 /*
79  * Returns TRUE if no ephemerons have been marked.  Will be called again if it returned
80  * FALSE.  If ephemerons are not supported, just return TRUE.
81  */
82 gboolean sgen_client_mark_ephemerons (ScanCopyContext ctx);
83
84 /*
85  * Clear ephemeron pairs with unreachable keys.
86  * We pass the copy func so we can figure out if an array was promoted or not.
87  */
88 void sgen_client_clear_unreachable_ephemerons (ScanCopyContext ctx);
89
90 /*
91  * This is called for objects that are larger than one card.  If it's possible to scan only
92  * parts of the object based on which cards are marked, do so and return TRUE.  Otherwise,
93  * return FALSE.
94  */
95 gboolean sgen_client_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, gboolean mod_union, ScanCopyContext ctx);
96
97 /*
98  * Called after nursery objects have been pinned.  No action is necessary.
99  */
100 void sgen_client_nursery_objects_pinned (void **definitely_pinned, int count);
101
102 /*
103  * Called at a semi-random point during minor collections.  No action is necessary.
104  */
105 void sgen_client_collecting_minor (SgenPointerQueue *fin_ready_queue, SgenPointerQueue *critical_fin_queue);
106
107 /*
108  * Called at semi-random points during major collections.  No action is necessary.
109  */
110 void sgen_client_collecting_major_1 (void);
111 void sgen_client_collecting_major_2 (void);
112 void sgen_client_collecting_major_3 (SgenPointerQueue *fin_ready_queue, SgenPointerQueue *critical_fin_queue);
113
114 /*
115  * Called after a LOS object has been pinned.  No action is necessary.
116  */
117 void sgen_client_pinned_los_object (char *obj);
118
119 /*
120  * Called for every degraded allocation.  No action is necessary.
121  */
122 void sgen_client_degraded_allocation (size_t size);
123
124 /*
125  * Called whenever the amount of memory allocated for the managed heap changes.  No action
126  * is necessary.
127  */
128 void sgen_client_total_allocated_heap_changed (size_t allocated_heap_size);
129
130 /*
131  * Called when an object allocation fails.  The suggested action is to abort the program.
132  *
133  * FIXME: Don't we want to return a BOOL here that indicates whether to retry the
134  * allocation?
135  */
136 void sgen_client_out_of_memory (size_t size);
137
138 /*
139  * If the client has registered any internal memory types, this must return a string
140  * describing the given type.  Only used for debugging.
141  */
142 const char* sgen_client_description_for_internal_mem_type (int type);
143
144 /*
145  * Only used for debugging.  `sgen_client_vtable_get_namespace()` may return NULL.
146  */
147 const char* sgen_client_vtable_get_namespace (GCVTable *vtable);
148 const char* sgen_client_vtable_get_name (GCVTable *vtable);
149
150 /*
151  * Called before starting collections.  The world is already stopped.  No action is
152  * necessary.
153  */
154 void sgen_client_pre_collection_checks (void);
155
156 /*
157  * Must set the thread's thread info to `info`.  If the thread's small ID was not already
158  * initialized in `sgen_client_init()` (for the main thread, usually), it must be done here.
159  *
160  * `stack_bottom_fallback` is the value passed through via `sgen_thread_register()`.
161  */
162 void sgen_client_thread_register (SgenThreadInfo* info, void *stack_bottom_fallback);
163
164 void sgen_client_thread_unregister (SgenThreadInfo *p);
165
166 /*
167  * Called on each worker thread when it starts up.  Must initialize the thread's small ID.
168  */
169 void sgen_client_thread_register_worker (void);
170
171 /*
172  * The least this function needs to do is scan all registers and thread stacks.  To do this
173  * conservatively, use `sgen_conservatively_pin_objects_from()`.
174  */
175 void sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, ScanCopyContext ctx);
176
177 /*
178  * Stop and restart the world, i.e., all threads that interact with the managed heap.  For
179  * single-threaded programs this is a nop.
180  */
181 void sgen_client_stop_world (int generation);
182 void sgen_client_restart_world (int generation, GGTimingInfo *timing);
183
184 /*
185  * Must return FALSE.  The bridge is not supported outside of Mono.
186  */
187 gboolean sgen_client_bridge_need_processing (void);
188
189 /*
190  * None of these should ever be called.
191  */
192 void sgen_client_bridge_reset_data (void);
193 void sgen_client_bridge_processing_stw_step (void);
194 void sgen_client_bridge_wait_for_processing (void);
195 void sgen_client_bridge_processing_finish (int generation);
196 gboolean sgen_client_bridge_is_bridge_object (GCObject *obj);
197 void sgen_client_bridge_register_finalized_object (GCObject *object);
198
199 /*
200  * No action is necessary.
201  */
202 void sgen_client_mark_togglerefs (char *start, char *end, ScanCopyContext ctx);
203 void sgen_client_clear_togglerefs (char *start, char *end, ScanCopyContext ctx);
204
205 /*
206  * Called after collections, reporting the amount of time they took.  No action is
207  * necessary.
208  */
209 void sgen_client_log_timing (GGTimingInfo *info, mword last_major_num_sections, mword last_los_memory_usage);
210
211 /*
212  * Called to handle `MONO_GC_PARAMS` and `MONO_GC_DEBUG` options.  The `handle` functions
213  * must return TRUE if they have recognized and processed the option, FALSE otherwise.
214  */
215 gboolean sgen_client_handle_gc_param (const char *opt);
216 void sgen_client_print_gc_params_usage (void);
217 gboolean sgen_client_handle_gc_debug (const char *opt);
218 void sgen_client_print_gc_debug_usage (void);
219
220 /*
221  * These client binary protocol functions are called from the respective binary protocol
222  * functions.  No action is necessary.  We suggest implementing them as inline functions in
223  * the client header file so that no overhead is incurred if they don't actually do
224  * anything.
225  */
226
227 #define TYPE_INT int
228 #define TYPE_LONGLONG long long
229 #define TYPE_SIZE size_t
230 #define TYPE_POINTER gpointer
231 #define TYPE_BOOL gboolean
232
233 #define BEGIN_PROTOCOL_ENTRY0(method) \
234         void sgen_client_ ## method (void);
235 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
236         void sgen_client_ ## method (void);
237 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
238         void sgen_client_ ## method (t1 f1);
239 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
240         void sgen_client_ ## method (t1 f1);
241 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
242         void sgen_client_ ## method (t1 f1, t2 f2);
243 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
244         void sgen_client_ ## method (t1 f1, t2 f2);
245 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
246         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3);
247 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
248         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3);
249 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
250         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4);
251 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
252         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4);
253 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
254         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5);
255 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
256         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5);
257 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
258         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
259 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
260         void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
261
262 #define FLUSH()
263
264 #define DEFAULT_PRINT()
265 #define CUSTOM_PRINT(_)
266
267 #define IS_ALWAYS_MATCH(_)
268 #define MATCH_INDEX(_)
269 #define IS_VTABLE_MATCH(_)
270
271 #define END_PROTOCOL_ENTRY
272 #define END_PROTOCOL_ENTRY_HEAVY
273
274 #include "sgen-protocol-def.h"
275
276 #undef TYPE_INT
277 #undef TYPE_LONGLONG
278 #undef TYPE_SIZE
279 #undef TYPE_POINTER
280 #undef TYPE_BOOL
281
282 #ifdef SGEN_WITHOUT_MONO
283 /*
284  * Get the current thread's thread info.  This will only be called on managed threads.
285  */
286 SgenThreadInfo* mono_thread_info_current (void);
287
288 /*
289  * Get the current thread's small ID.  This will be called on managed and worker threads.
290  */
291 int mono_thread_info_get_small_id (void);
292 #endif