Reduce TLS accesses. (#11487)
[mono-project.git] / mono / metadata / gc-internals.h
blobb0cc11d2e9151d0a90f03281a060f6dfb42d7a7b
1 /**
2 * \file
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__
15 #include <glib.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)); \
41 } while (0)
44 * This is used for fields which point to objects which are kept alive by other references
45 * when using Boehm.
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); \
50 } while (0)
52 #define MONO_GC_UNREGISTER_ROOT_IF_MOVING(x) do { \
53 if (mono_gc_is_moving ()) \
54 MONO_GC_UNREGISTER_ROOT (x); \
55 } while (0)
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);
62 void
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)
94 * mark_func (ref)
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.
115 MonoObject*
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);
126 MonoObject*
127 mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size);
129 MonoObjectHandle
130 mono_gc_alloc_handle_pinned_obj (MonoVTable *vtable, gsize size);
132 MonoObject*
133 mono_gc_alloc_obj (MonoVTable *vtable, size_t size);
135 MonoObjectHandle
136 mono_gc_alloc_handle_obj (MonoVTable *vtable, gsize size);
138 MonoArray*
139 mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length);
141 MonoArrayHandle
142 mono_gc_alloc_handle_vector (MonoVTable *vtable, gsize size, gsize max_length);
144 MonoArray*
145 mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uintptr_t bounds_size);
147 MonoArrayHandle
148 mono_gc_alloc_handle_array (MonoVTable *vtable, gsize size, gsize max_length, gsize bounds_size);
150 MonoString*
151 mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len);
153 MonoStringHandle
154 mono_gc_alloc_handle_string (MonoVTable *vtable, gsize size, gint32 len);
156 MonoObject*
157 mono_gc_alloc_mature (MonoVTable *vtable, size_t size);
159 MonoGCDescriptor mono_gc_make_descr_for_string (gsize *bitmap, int numbits);
161 MonoObjectHandle
162 mono_gc_alloc_handle_mature (MonoVTable *vtable, gsize size);
164 void mono_gc_register_obj_with_weak_fields (void *obj);
165 void
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
187 * is more efficient.
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); \
198 } while (0)
200 /* fast allocation support */
202 typedef enum {
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 */
236 ICALL_EXPORT
237 MonoString *
238 ves_icall_string_alloc (int length);
241 * Functions supplied by the runtime and called by the GC. Currently only used
242 * by SGEN.
244 typedef struct {
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);
276 } MonoGCCallbacks;
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);
329 #ifndef HOST_WIN32
330 int mono_gc_pthread_create (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
331 #endif
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);
348 #endif
350 gboolean mono_gc_precise_stack_mark_enabled (void);
352 typedef struct _RefQueueEntry RefQueueEntry;
354 struct _RefQueueEntry {
355 void *dis_link;
356 guint32 gchandle;
357 MonoDomain *domain;
358 void *user_data;
359 RefQueueEntry *next;
362 struct _MonoReferenceQueue {
363 RefQueueEntry *queue;
364 mono_reference_queue_callback callback;
365 MonoReferenceQueue *next;
366 gboolean should_be_deleted;
369 enum {
370 MONO_GC_FINALIZER_EXTENSION_VERSION = 1,
373 typedef struct {
374 int version;
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);
382 #ifdef HOST_WIN32
383 BOOL APIENTRY mono_gc_dllmain (HMODULE module_handle, DWORD reason, LPVOID reserved);
384 #endif
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__ */