2 * sgen-client.h: SGen client interface.
4 * Copyright (C) 2014 Xamarin Inc
6 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9 #include "mono/sgen/sgen-pointer-queue.h"
12 * Init whatever needs initing. This is called relatively early in SGen initialization.
13 * Must initialized the small ID for the current thread.
15 void sgen_client_init (void);
18 * The slow path for getting an object's size. We're passing in the vtable because we've
21 mword
sgen_client_slow_object_get_size (GCVTable vtable
, GCObject
* o
);
24 * Fill the given range with a dummy object. If the range is too short to be filled with an
25 * object, null it. Return `TRUE` if the range was filled with an object, `FALSE` if it was
28 gboolean
sgen_client_array_fill_range (char *start
, size_t size
);
31 * This is called if the nursery clearing policy at `clear-at-gc`, which is usually only
32 * used for debugging. If `size` is large enough for the memory to have been filled with a
33 * dummy, object, zero its header. Note that there might not actually be a header there.
35 void sgen_client_zero_array_fill_header (void *p
, size_t size
);
38 * Return whether the given object is an array fill dummy object.
40 gboolean
sgen_client_object_is_array_fill (GCObject
*o
);
43 * Return whether the given finalizable object's finalizer is critical, i.e., needs to run
44 * after all non-critical finalizers have run.
46 gboolean
sgen_client_object_has_critical_finalizer (GCObject
*obj
);
49 * Called after an object is enqueued for finalization. This is a very low-level callback.
50 * It should almost certainly be a NOP.
52 * FIXME: Can we merge this with `sgen_client_object_has_critical_finalizer()`?
54 void sgen_client_object_queued_for_finalization (GCObject
*obj
);
57 * Run the given object's finalizer.
59 void sgen_client_run_finalize (GCObject
*obj
);
62 * Is called after a collection if there are objects to finalize. The world is still
63 * stopped. This will usually notify the finalizer thread that it needs to run.
65 void sgen_client_finalize_notify (void);
68 * Returns TRUE if no ephemerons have been marked. Will be called again if it returned
69 * FALSE. If ephemerons are not supported, just return TRUE.
71 gboolean
sgen_client_mark_ephemerons (ScanCopyContext ctx
);
74 * Clear ephemeron pairs with unreachable keys.
75 * We pass the copy func so we can figure out if an array was promoted or not.
77 void sgen_client_clear_unreachable_ephemerons (ScanCopyContext ctx
);
80 * May return NULL. Must be an aligned pointer.
82 gpointer
sgen_client_default_metadata (void);
83 gpointer
sgen_client_metadata_for_object (GCObject
*obj
);
88 void sgen_client_gchandle_created (int handle_type
, GCObject
*obj
, guint32 handle
);
89 void sgen_client_gchandle_destroyed (int handle_type
, guint32 handle
);
90 void sgen_client_ensure_weak_gchandles_accessible (void);
93 * This is called for objects that are larger than one card. If it's possible to scan only
94 * parts of the object based on which cards are marked, do so and return TRUE. Otherwise,
97 gboolean
sgen_client_cardtable_scan_object (GCObject
*obj
, mword block_obj_size
, guint8
*cards
, ScanCopyContext ctx
);
100 * Called after nursery objects have been pinned. No action is necessary.
102 void sgen_client_nursery_objects_pinned (void **definitely_pinned
, int count
);
105 * Called at a semi-random point during minor collections. No action is necessary.
107 void sgen_client_collecting_minor (SgenPointerQueue
*fin_ready_queue
, SgenPointerQueue
*critical_fin_queue
);
110 * Called at semi-random points during major collections. No action is necessary.
112 void sgen_client_collecting_major_1 (void);
113 void sgen_client_collecting_major_2 (void);
114 void sgen_client_collecting_major_3 (SgenPointerQueue
*fin_ready_queue
, SgenPointerQueue
*critical_fin_queue
);
117 * Called after a LOS object has been pinned. No action is necessary.
119 void sgen_client_pinned_los_object (GCObject
*obj
);
122 * Called for every degraded allocation. No action is necessary.
124 void sgen_client_degraded_allocation (size_t size
);
127 * Called whenever the amount of memory allocated for the managed heap changes. No action
130 void sgen_client_total_allocated_heap_changed (size_t allocated_heap_size
);
133 * If the client has registered any internal memory types, this must return a string
134 * describing the given type. Only used for debugging.
136 const char* sgen_client_description_for_internal_mem_type (int type
);
139 * Only used for debugging. `sgen_client_vtable_get_namespace()` may return NULL.
141 gboolean
sgen_client_vtable_is_inited (GCVTable vtable
);
142 const char* sgen_client_vtable_get_namespace (GCVTable vtable
);
143 const char* sgen_client_vtable_get_name (GCVTable vtable
);
146 * Called before starting collections. The world is already stopped. No action is
149 void sgen_client_pre_collection_checks (void);
152 * Must set the thread's thread info to `info`. If the thread's small ID was not already
153 * initialized in `sgen_client_init()` (for the main thread, usually), it must be done here.
155 * `stack_bottom_fallback` is the value passed through via `sgen_thread_register()`.
157 void sgen_client_thread_register (SgenThreadInfo
* info
, void *stack_bottom_fallback
);
159 void sgen_client_thread_unregister (SgenThreadInfo
*p
);
162 * Called on each worker thread when it starts up. Must initialize the thread's small ID.
164 void sgen_client_thread_register_worker (void);
167 * The least this function needs to do is scan all registers and thread stacks. To do this
168 * conservatively, use `sgen_conservatively_pin_objects_from()`.
170 void sgen_client_scan_thread_data (void *start_nursery
, void *end_nursery
, gboolean precise
, ScanCopyContext ctx
);
173 * Stop and restart the world, i.e., all threads that interact with the managed heap. For
174 * single-threaded programs this is a nop.
176 void sgen_client_stop_world (int generation
);
177 void sgen_client_restart_world (int generation
, gint64
*stw_time
);
180 * Must return FALSE. The bridge is not supported outside of Mono.
182 gboolean
sgen_client_bridge_need_processing (void);
185 * None of these should ever be called.
187 void sgen_client_bridge_reset_data (void);
188 void sgen_client_bridge_processing_stw_step (void);
189 void sgen_client_bridge_wait_for_processing (void);
190 void sgen_client_bridge_processing_finish (int generation
);
191 gboolean
sgen_client_bridge_is_bridge_object (GCObject
*obj
);
192 void sgen_client_bridge_register_finalized_object (GCObject
*object
);
195 * No action is necessary.
197 void sgen_client_mark_togglerefs (char *start
, char *end
, ScanCopyContext ctx
);
198 void sgen_client_clear_togglerefs (char *start
, char *end
, ScanCopyContext ctx
);
201 * Called to handle `MONO_GC_PARAMS` and `MONO_GC_DEBUG` options. The `handle` functions
202 * must return TRUE if they have recognized and processed the option, FALSE otherwise.
204 gboolean
sgen_client_handle_gc_param (const char *opt
);
205 void sgen_client_print_gc_params_usage (void);
206 gboolean
sgen_client_handle_gc_debug (const char *opt
);
207 void sgen_client_print_gc_debug_usage (void);
210 * Called to obtain an identifier for the current location, such as a method pointer. This
211 * is used for logging the provenances of allocations with the heavy binary protocol.
213 gpointer
sgen_client_get_provenance (void);
216 * Called by the debugging infrastructure to describe pointers that have an invalid vtable.
217 * Should usually print to `stdout`.
219 void sgen_client_describe_invalid_pointer (GCObject
*ptr
);
222 * These client binary protocol functions are called from the respective binary protocol
223 * functions. No action is necessary. We suggest implementing them as inline functions in
224 * the client header file so that no overhead is incurred if they don't actually do
229 #define TYPE_LONGLONG long long
230 #define TYPE_SIZE size_t
231 #define TYPE_POINTER gpointer
232 #define TYPE_BOOL gboolean
234 #define BEGIN_PROTOCOL_ENTRY0(method) \
235 void sgen_client_ ## method (void);
236 #define BEGIN_PROTOCOL_ENTRY_HEAVY0(method) \
237 void sgen_client_ ## method (void);
238 #define BEGIN_PROTOCOL_ENTRY1(method,t1,f1) \
239 void sgen_client_ ## method (t1 f1);
240 #define BEGIN_PROTOCOL_ENTRY_HEAVY1(method,t1,f1) \
241 void sgen_client_ ## method (t1 f1);
242 #define BEGIN_PROTOCOL_ENTRY2(method,t1,f1,t2,f2) \
243 void sgen_client_ ## method (t1 f1, t2 f2);
244 #define BEGIN_PROTOCOL_ENTRY_HEAVY2(method,t1,f1,t2,f2) \
245 void sgen_client_ ## method (t1 f1, t2 f2);
246 #define BEGIN_PROTOCOL_ENTRY3(method,t1,f1,t2,f2,t3,f3) \
247 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3);
248 #define BEGIN_PROTOCOL_ENTRY_HEAVY3(method,t1,f1,t2,f2,t3,f3) \
249 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3);
250 #define BEGIN_PROTOCOL_ENTRY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
251 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4);
252 #define BEGIN_PROTOCOL_ENTRY_HEAVY4(method,t1,f1,t2,f2,t3,f3,t4,f4) \
253 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4);
254 #define BEGIN_PROTOCOL_ENTRY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
255 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5);
256 #define BEGIN_PROTOCOL_ENTRY_HEAVY5(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5) \
257 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5);
258 #define BEGIN_PROTOCOL_ENTRY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
259 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
260 #define BEGIN_PROTOCOL_ENTRY_HEAVY6(method,t1,f1,t2,f2,t3,f3,t4,f4,t5,f5,t6,f6) \
261 void sgen_client_ ## method (t1 f1, t2 f2, t3 f3, t4 f4, t5 f5, t6 f6);
263 #define DEFAULT_PRINT()
264 #define CUSTOM_PRINT(_)
266 #define IS_ALWAYS_MATCH(_)
267 #define MATCH_INDEX(_)
268 #define IS_VTABLE_MATCH(_)
270 #define END_PROTOCOL_ENTRY
271 #define END_PROTOCOL_ENTRY_FLUSH
272 #define END_PROTOCOL_ENTRY_HEAVY
274 #include "sgen-protocol-def.h"
282 #ifdef SGEN_WITHOUT_MONO
284 * Get the current thread's thread info. This will only be called on managed threads.
286 SgenThreadInfo
* mono_thread_info_current (void);
289 * Get the current thread's small ID. This will be called on managed and worker threads.
291 int mono_thread_info_get_small_id (void);