3 * Internal GC interface
5 * Author: Paolo Molaro <lupus@ximian.com>
7 * (C) 2002 Ximian, Inc.
8 * Copyright 2012 Xamarin Inc (http://www.xamarin.com)
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #ifndef __MONO_METADATA_GC_INTERNAL_H__
13 #define __MONO_METADATA_GC_INTERNAL_H__
16 #include <mono/utils/gc_wrapper.h>
17 #include <mono/metadata/object-internals.h>
18 #include <mono/metadata/threads-types.h>
19 #include <mono/sgen/gc-internal-agnostic.h>
20 #include <mono/metadata/icalls.h>
22 #define mono_domain_finalizers_lock(domain) mono_os_mutex_lock (&(domain)->finalizable_objects_hash_lock);
23 #define mono_domain_finalizers_unlock(domain) mono_os_mutex_unlock (&(domain)->finalizable_objects_hash_lock);
25 /* Register a memory area as a conservatively scanned GC root */
26 #define MONO_GC_REGISTER_ROOT_PINNING(x,src,key,msg) mono_gc_register_root ((char*)&(x), sizeof(x), MONO_GC_DESCRIPTOR_NULL, (src), (key), (msg))
28 #define MONO_GC_UNREGISTER_ROOT(x) mono_gc_deregister_root ((char*)&(x))
31 * Return a GC descriptor for an array containing N pointers to memory allocated
32 * by mono_gc_alloc_fixed ().
34 /* For SGEN, the result of alloc_fixed () is not GC tracked memory */
35 #define MONO_GC_ROOT_DESCR_FOR_FIXED(n) (mono_gc_is_moving () ? mono_gc_make_root_descr_all_refs (0) : MONO_GC_DESCRIPTOR_NULL)
37 /* Register a memory location holding a single object reference as a GC root */
38 #define MONO_GC_REGISTER_ROOT_SINGLE(x,src,key,msg) do { \
39 g_assert (sizeof (x) == sizeof (MonoObject*)); \
40 mono_gc_register_root ((char*)&(x), sizeof(MonoObject*), mono_gc_make_root_descr_all_refs (1), (src), (key),(msg)); \
44 * This is used for fields which point to objects which are kept alive by other references
47 #define MONO_GC_REGISTER_ROOT_IF_MOVING(x,src,key,msg) do { \
48 if (mono_gc_is_moving ()) \
49 MONO_GC_REGISTER_ROOT_SINGLE(x,src,key,msg); \
52 #define MONO_GC_UNREGISTER_ROOT_IF_MOVING(x) do { \
53 if (mono_gc_is_moving ()) \
54 MONO_GC_UNREGISTER_ROOT (x); \
57 /* useful until we keep track of gc-references in corlib etc. */
58 #define IS_GC_REFERENCE(class,t) (mono_gc_is_moving () ? FALSE : ((t)->type == MONO_TYPE_U && (class)->image == mono_defaults.corlib))
60 void mono_object_register_finalizer (MonoObject
*obj
);
63 mono_object_register_finalizer_handle (MonoObjectHandle obj
);
65 extern void mono_gc_init (void);
66 extern void mono_gc_base_init (void);
67 extern void mono_gc_cleanup (void);
68 extern void mono_gc_base_cleanup (void);
71 * Return whenever the current thread is registered with the GC (i.e. started
72 * by the GC pthread wrappers on unix.
74 extern gboolean
mono_gc_is_gc_thread (void);
76 extern gboolean
mono_gc_is_finalizer_internal_thread (MonoInternalThread
*thread
);
78 extern void mono_gc_set_stack_end (void *stack_end
);
80 /* only valid after the RECLAIM_START GC event and before RECLAIM_END
81 * Not exported in public headers, but can be linked to (unsupported).
83 gboolean
mono_object_is_alive (MonoObject
* obj
);
84 gboolean
mono_gc_is_finalizer_thread (MonoThread
*thread
);
86 void mono_gchandle_set_target (guint32 gchandle
, MonoObject
*obj
);
88 /*Ephemeron functionality. Sgen only*/
89 gboolean
mono_gc_ephemeron_array_add (MonoObject
*obj
);
91 /* User defined marking function */
92 /* It should work like this:
93 * foreach (ref in GC references in the are structure pointed to by ADDR)
96 typedef void (*MonoGCMarkFunc
) (MonoObject
**addr
, void *gc_data
);
97 typedef void (*MonoGCRootMarkFunc
) (void *addr
, MonoGCMarkFunc mark_func
, void *gc_data
);
99 /* Create a descriptor with a user defined marking function */
100 MonoGCDescriptor
mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker
);
102 /* Return whenever user defined marking functions are supported */
103 gboolean
mono_gc_user_markers_supported (void);
105 /* desc is the result from mono_gc_make_descr*. A NULL value means
106 * all the words might contain GC pointers.
107 * The memory is non-moving and it will be explicitly deallocated.
108 * size bytes will be available from the returned address (ie, descr
109 * must not be stored in the returned memory)
111 MonoObject
* mono_gc_alloc_fixed (size_t size
, MonoGCDescriptor descr
, MonoGCRootSource source
, void *key
, const char *msg
);
113 // C++ callers outside of metadata (mini/tasklets.c) must use mono_gc_alloc_fixed_no_descriptor
114 // instead of mono_gc_alloc_fixed, or else compile twice -- boehm and sgen.
116 mono_gc_alloc_fixed_no_descriptor (size_t size
, MonoGCRootSource source
, void *key
, const char *msg
);
118 void mono_gc_free_fixed (void* addr
);
120 /* make sure the gchandle was allocated for an object in domain */
121 gboolean
mono_gchandle_is_in_domain (guint32 gchandle
, MonoDomain
*domain
);
122 void mono_gchandle_free_domain (MonoDomain
*domain
);
124 typedef void (*FinalizerThreadCallback
) (gpointer user_data
);
127 mono_gc_alloc_pinned_obj (MonoVTable
*vtable
, size_t size
);
130 mono_gc_alloc_handle_pinned_obj (MonoVTable
*vtable
, gsize size
);
133 mono_gc_alloc_obj (MonoVTable
*vtable
, size_t size
);
136 mono_gc_alloc_handle_obj (MonoVTable
*vtable
, gsize size
);
139 mono_gc_alloc_vector (MonoVTable
*vtable
, size_t size
, uintptr_t max_length
);
142 mono_gc_alloc_handle_vector (MonoVTable
*vtable
, gsize size
, gsize max_length
);
145 mono_gc_alloc_array (MonoVTable
*vtable
, size_t size
, uintptr_t max_length
, uintptr_t bounds_size
);
148 mono_gc_alloc_handle_array (MonoVTable
*vtable
, gsize size
, gsize max_length
, gsize bounds_size
);
151 mono_gc_alloc_string (MonoVTable
*vtable
, size_t size
, gint32 len
);
154 mono_gc_alloc_handle_string (MonoVTable
*vtable
, gsize size
, gint32 len
);
157 mono_gc_alloc_mature (MonoVTable
*vtable
, size_t size
);
159 MonoGCDescriptor
mono_gc_make_descr_for_string (gsize
*bitmap
, int numbits
);
162 mono_gc_alloc_handle_mature (MonoVTable
*vtable
, gsize size
);
164 void mono_gc_register_obj_with_weak_fields (void *obj
);
166 mono_gc_register_object_with_weak_fields (MonoObjectHandle obj
);
168 typedef void (*MonoFinalizationProc
)(gpointer
, gpointer
); // same as SGenFinalizationProc, GC_finalization_proc
170 void mono_gc_register_for_finalization (MonoObject
*obj
, MonoFinalizationProc user_data
);
171 void mono_gc_add_memory_pressure (gint64 value
);
172 MONO_API
int mono_gc_register_root (char *start
, size_t size
, MonoGCDescriptor descr
, MonoGCRootSource source
, void *key
, const char *msg
);
173 void mono_gc_deregister_root (char* addr
);
174 void mono_gc_finalize_domain (MonoDomain
*domain
);
175 void mono_gc_run_finalize (void *obj
, void *data
);
176 void mono_gc_clear_domain (MonoDomain
* domain
);
177 /* Signal early termination of finalizer processing inside the gc */
178 void mono_gc_suspend_finalizers (void);
182 * Register a root which can only be written using a write barrier.
183 * Writes to the root must be done using a write barrier (MONO_ROOT_SETREF).
184 * If the root uses an user defined mark routine, the writes are not required to be
185 * to the area between START and START+SIZE.
186 * The write barrier allows the GC to avoid scanning this root at each collection, so it
188 * FIXME: Add an API for clearing remset entries if a root with a user defined
189 * mark routine is deleted.
191 int mono_gc_register_root_wbarrier (char *start
, size_t size
, MonoGCDescriptor descr
, MonoGCRootSource source
, void *key
, const char *msg
);
193 void mono_gc_wbarrier_set_root (gpointer ptr
, MonoObject
*value
);
195 /* Set a field of a root registered using mono_gc_register_root_wbarrier () */
196 #define MONO_ROOT_SETREF(s,fieldname,value) do { \
197 mono_gc_wbarrier_set_root (&((s)->fieldname), (MonoObject*)value); \
200 /* fast allocation support */
203 // Regular fast path allocator.
204 MANAGED_ALLOCATOR_REGULAR
,
205 // Managed allocator that just calls into the runtime.
206 MANAGED_ALLOCATOR_SLOW_PATH
,
207 // Managed allocator that works like the regular one but also calls into the profiler.
208 MANAGED_ALLOCATOR_PROFILER
,
209 } ManagedAllocatorVariant
;
211 int mono_gc_get_aligned_size_for_allocator (int size
);
212 MonoMethod
* mono_gc_get_managed_allocator (MonoClass
*klass
, gboolean for_box
, gboolean known_instance_size
);
213 MonoMethod
* mono_gc_get_managed_array_allocator (MonoClass
*klass
);
214 MonoMethod
*mono_gc_get_managed_allocator_by_type (int atype
, ManagedAllocatorVariant variant
);
216 guint32
mono_gc_get_managed_allocator_types (void);
218 /* Return a short string identifying the GC, indented to be saved in AOT images */
219 const char *mono_gc_get_gc_name (void);
221 /* Fast write barriers */
222 MonoMethod
* mono_gc_get_specific_write_barrier (gboolean is_concurrent
);
223 MonoMethod
* mono_gc_get_write_barrier (void);
225 /* Fast valuetype copy */
226 /* WARNING: [dest, dest + size] must be within the bounds of a single type, otherwise the GC will lose remset entries */
227 G_EXTERN_C
void mono_gc_wbarrier_range_copy (gpointer dest
, gconstpointer src
, int size
);
229 typedef void (*MonoRangeCopyFunction
)(gpointer
, gconstpointer
, int size
);
231 MonoRangeCopyFunction
232 mono_gc_get_range_copy_func (void);
235 /* helper for the managed alloc support */
238 ves_icall_string_alloc (int length
);
241 * Functions supplied by the runtime and called by the GC. Currently only used
246 * Function called during thread startup/attach to allocate thread-local data
247 * needed by the other functions.
249 gpointer (*thread_attach_func
) (void);
251 * Function called during thread deatch to free the data allocated by
252 * thread_attach_func.
254 void (*thread_detach_func
) (gpointer user_data
);
256 * Function called from every thread when suspending for GC. It can save
257 * data needed for marking from thread stacks. user_data is the data returned
258 * by attach_func. This might called with GC locks held and the word stopped,
259 * so it shouldn't do any synchronization etc.
261 void (*thread_suspend_func
) (gpointer user_data
, void *sigcontext
, MonoContext
*ctx
);
263 * Function called to mark from thread stacks. user_data is the data returned
264 * by attach_func. This is called twice, with the word stopped:
265 * - in the first pass, it should mark areas of the stack using
266 * conservative marking by calling mono_gc_conservatively_scan_area ().
267 * - in the second pass, it should mark the remaining areas of the stack
268 * using precise marking by calling mono_gc_scan_object ().
270 void (*thread_mark_func
) (gpointer user_data
, guint8
*stack_start
, guint8
*stack_end
, gboolean precise
, void *gc_data
);
272 * Function called for debugging to get the current managed method for
273 * tracking the provenances of objects.
275 gpointer (*get_provenance_func
) (void);
278 /* Set the callback functions callable by the GC */
279 void mono_gc_set_gc_callbacks (MonoGCCallbacks
*callbacks
);
280 MonoGCCallbacks
*mono_gc_get_gc_callbacks (void);
282 /* Functions callable from the thread mark func */
284 /* Scan the memory area between START and END conservatively */
285 void mono_gc_conservatively_scan_area (void *start
, void *end
);
287 /* Scan OBJ, returning its new address */
288 void *mono_gc_scan_object (void *obj
, void *gc_data
);
290 /* Return the suspend signal number used by the GC to suspend threads,
291 or -1 if not applicable. */
292 int mono_gc_get_suspend_signal (void);
294 /* Return the suspend signal number used by the GC to suspend threads,
295 or -1 if not applicable. */
296 int mono_gc_get_restart_signal (void);
299 * Return a human readable description of the GC in malloc-ed memory.
301 char* mono_gc_get_description (void);
304 * Configure the GC to desktop mode
306 void mono_gc_set_desktop_mode (void);
309 * Return whenever this GC can move objects
311 gboolean
mono_gc_is_moving (void);
313 typedef void* (*MonoGCLockedCallbackFunc
) (void *data
);
315 void* mono_gc_invoke_with_gc_lock (MonoGCLockedCallbackFunc func
, void *data
);
317 int mono_gc_get_los_limit (void);
319 guint8
* mono_gc_get_card_table (int *shift_bits
, gpointer
*card_mask
);
320 guint8
* mono_gc_get_target_card_table (int *shift_bits
, target_mgreg_t
*card_mask
);
321 gboolean
mono_gc_card_table_nursery_check (void);
323 void* mono_gc_get_nursery (int *shift_bits
, size_t *size
);
325 // Don't use directly; set/unset MONO_THREAD_INFO_FLAGS_NO_GC instead.
326 void mono_gc_skip_thread_changing (gboolean skip
);
327 void mono_gc_skip_thread_changed (gboolean skip
);
330 int mono_gc_pthread_create (pthread_t
*new_thread
, const pthread_attr_t
*attr
, void *(*start_routine
)(void *), void *arg
);
334 * Return whenever GC is disabled
336 gboolean
mono_gc_is_disabled (void);
339 * Return whenever this is the null GC
341 gboolean
mono_gc_is_null (void);
343 void mono_gc_set_string_length (MonoString
*str
, gint32 new_length
);
345 #if defined(__MACH__)
346 void mono_gc_register_mach_exception_thread (pthread_t thread
);
347 pthread_t
mono_gc_get_mach_exception_thread (void);
350 gboolean
mono_gc_precise_stack_mark_enabled (void);
352 typedef struct _RefQueueEntry RefQueueEntry
;
354 struct _RefQueueEntry
{
362 struct _MonoReferenceQueue
{
363 RefQueueEntry
*queue
;
364 mono_reference_queue_callback callback
;
365 MonoReferenceQueue
*next
;
366 gboolean should_be_deleted
;
370 MONO_GC_FINALIZER_EXTENSION_VERSION
= 1,
375 gboolean (*is_class_finalization_aware
) (MonoClass
*klass
);
376 void (*object_queued_for_finalization
) (MonoObject
*object
);
377 } MonoGCFinalizerCallbacks
;
379 MONO_API
void mono_gc_register_finalizer_callbacks (MonoGCFinalizerCallbacks
*callbacks
);
383 BOOL APIENTRY
mono_gc_dllmain (HMODULE module_handle
, DWORD reason
, LPVOID reserved
);
386 MonoVTable
*mono_gc_get_vtable (MonoObject
*obj
);
388 guint
mono_gc_get_vtable_bits (MonoClass
*klass
);
390 void mono_gc_register_altstack (gpointer stack
, gint32 stack_size
, gpointer altstack
, gint32 altstack_size
);
392 gboolean
mono_gc_is_critical_method (MonoMethod
*method
);
394 G_EXTERN_C
// due to THREAD_INFO_TYPE varying
395 gpointer
mono_gc_thread_attach (THREAD_INFO_TYPE
*info
);
397 G_EXTERN_C
// due to THREAD_INFO_TYPE varying
398 void mono_gc_thread_detach_with_lock (THREAD_INFO_TYPE
*info
);
400 G_EXTERN_C
// due to THREAD_INFO_TYPE varying
401 gboolean
mono_gc_thread_in_critical_region (THREAD_INFO_TYPE
*info
);
403 /* If set, print debugging messages around finalizers. */
404 extern gboolean mono_log_finalizers
;
406 /* If set, do not run finalizers. */
407 extern gboolean mono_do_not_finalize
;
408 /* List of names of classes not to finalize. */
409 extern gchar
**mono_do_not_finalize_class_names
;
411 #endif /* __MONO_METADATA_GC_INTERNAL_H__ */