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