/
gc-internal.h
363 lines (289 loc) · 14.3 KB
/
gc-internal.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/*
* metadata/gc-internal.h: Internal GC interface
*
* Author: Paolo Molaro <lupus@ximian.com>
*
* (C) 2002 Ximian, Inc.
*/
#ifndef __MONO_METADATA_GC_INTERNAL_H__
#define __MONO_METADATA_GC_INTERNAL_H__
#include <glib.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/utils/gc_wrapper.h>
#define mono_domain_finalizers_lock(domain) EnterCriticalSection (&(domain)->finalizable_objects_hash_lock);
#define mono_domain_finalizers_unlock(domain) LeaveCriticalSection (&(domain)->finalizable_objects_hash_lock);
/* Register a memory area as a conservatively scanned GC root */
#define MONO_GC_REGISTER_ROOT(x) mono_gc_register_root ((char*)&(x), sizeof(x), NULL)
#define MONO_GC_UNREGISTER_ROOT(x) mono_gc_deregister_root ((char*)&(x))
/*
* Register a memory location as a root pointing to memory allocated using
* mono_gc_alloc_fixed (). This includes MonoGHashTable.
*/
#ifdef HAVE_SGEN_GC
/* The result of alloc_fixed () is not GC tracked memory */
#define MONO_GC_REGISTER_ROOT_FIXED(x)
#else
#define MONO_GC_REGISTER_ROOT_FIXED(x) MONO_GC_REGISTER_ROOT ((x))
#endif
/*
* Return a GC descriptor for an array containing N pointers to memory allocated
* by mono_gc_alloc_fixed ().
*/
#ifdef HAVE_SGEN_GC
/* The result of alloc_fixed () is not GC tracked memory */
#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) mono_gc_make_root_descr_all_refs (0)
#else
/* The result of alloc_fixed () is GC tracked memory */
#define MONO_GC_ROOT_DESCR_FOR_FIXED(n) NULL
#endif
/* Register a memory location holding a single object reference as a GC root */
#define MONO_GC_REGISTER_ROOT_SINGLE(x) do { \
g_assert (sizeof (x) == sizeof (MonoObject*)); \
mono_gc_register_root ((char*)&(x), sizeof(MonoObject*), mono_gc_make_root_descr_all_refs (1)); \
} while (0)
/*
* This is used for fields which point to objects which are kept alive by other references
* when using Boehm.
*/
#ifdef HAVE_SGEN_GC
#define MONO_GC_REGISTER_ROOT_IF_MOVING(x) do { \
MONO_GC_REGISTER_ROOT_SINGLE(x); \
} while (0)
#define MONO_GC_UNREGISTER_ROOT_IF_MOVING(x) do { \
MONO_GC_UNREGISTER_ROOT (x); \
} while (0)
#else
#define MONO_GC_REGISTER_ROOT_IF_MOVING(x)
#define MONO_GC_UNREGISTER_ROOT_IF_MOVING(x)
#endif
/* useful until we keep track of gc-references in corlib etc. */
#ifdef HAVE_SGEN_GC
#define IS_GC_REFERENCE(t) FALSE
#else
#define IS_GC_REFERENCE(t) ((t)->type == MONO_TYPE_U && class->image == mono_defaults.corlib)
#endif
void mono_object_register_finalizer (MonoObject *obj) MONO_INTERNAL;
void ves_icall_System_GC_InternalCollect (int generation) MONO_INTERNAL;
gint64 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection) MONO_INTERNAL;
void ves_icall_System_GC_KeepAlive (MonoObject *obj) MONO_INTERNAL;
void ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj) MONO_INTERNAL;
void ves_icall_System_GC_SuppressFinalize (MonoObject *obj) MONO_INTERNAL;
void ves_icall_System_GC_WaitForPendingFinalizers (void) MONO_INTERNAL;
MonoObject *ves_icall_System_GCHandle_GetTarget (guint32 handle) MONO_INTERNAL;
guint32 ves_icall_System_GCHandle_GetTargetHandle (MonoObject *obj, guint32 handle, gint32 type) MONO_INTERNAL;
void ves_icall_System_GCHandle_FreeHandle (guint32 handle) MONO_INTERNAL;
gpointer ves_icall_System_GCHandle_GetAddrOfPinnedObject (guint32 handle) MONO_INTERNAL;
void ves_icall_System_GC_register_ephemeron_array (MonoObject *array) MONO_INTERNAL;
MonoObject *ves_icall_System_GC_get_ephemeron_tombstone (void) MONO_INTERNAL;
extern void mono_gc_init (void) MONO_INTERNAL;
extern void mono_gc_base_init (void) MONO_INTERNAL;
extern void mono_gc_cleanup (void) MONO_INTERNAL;
/*
* Return whenever the current thread is registered with the GC (i.e. started
* by the GC pthread wrappers on unix.
*/
extern gboolean mono_gc_is_gc_thread (void) MONO_INTERNAL;
/*
* Try to register a foreign thread with the GC, if we fail or the backend
* can't cope with this concept - we return FALSE.
*/
extern gboolean mono_gc_register_thread (void *baseptr) MONO_INTERNAL;
extern gboolean mono_gc_is_finalizer_internal_thread (MonoInternalThread *thread) MONO_INTERNAL;
extern void mono_gc_set_stack_end (void *stack_end) MONO_INTERNAL;
/* only valid after the RECLAIM_START GC event and before RECLAIM_END
* Not exported in public headers, but can be linked to (unsupported).
*/
extern gboolean mono_object_is_alive (MonoObject* obj);
extern gboolean mono_gc_is_finalizer_thread (MonoThread *thread);
extern gpointer mono_gc_out_of_memory (size_t size);
extern void mono_gc_enable_events (void);
/* disappearing link functionality */
void mono_gc_weak_link_add (void **link_addr, MonoObject *obj, gboolean track) MONO_INTERNAL;
void mono_gc_weak_link_remove (void **link_addr, gboolean track) MONO_INTERNAL;
MonoObject *mono_gc_weak_link_get (void **link_addr) MONO_INTERNAL;
/*Ephemeron functionality. Sgen only*/
gboolean mono_gc_ephemeron_array_add (MonoObject *obj) MONO_INTERNAL;
MonoBoolean
GCHandle_CheckCurrentDomain (guint32 gchandle) MONO_INTERNAL;
/* simple interface for data structures needed in the runtime */
void* mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits) MONO_INTERNAL;
/* Return a root descriptor for a root with all refs */
void* mono_gc_make_root_descr_all_refs (int numbits) MONO_INTERNAL;
/* User defined marking function */
/* It should work like this:
* foreach (ref in GC references in the are structure pointed to by ADDR)
* mark_func (ref)
*/
typedef void (*MonoGCMarkFunc) (void **addr);
typedef void (*MonoGCRootMarkFunc) (void *addr, MonoGCMarkFunc mark_func);
/* Create a descriptor with a user defined marking function */
void *mono_gc_make_root_descr_user (MonoGCRootMarkFunc marker);
/* desc is the result from mono_gc_make_descr*. A NULL value means
* all the words might contain GC pointers.
* The memory is non-moving and it will be explicitly deallocated.
* size bytes will be available from the returned address (ie, descr
* must not be stored in the returned memory)
* NOTE: Under Boehm, this returns memory allocated using GC_malloc, so the result should
* be stored into a location registered using MONO_GC_REGISTER_ROOT_FIXED ().
*/
void* mono_gc_alloc_fixed (size_t size, void *descr) MONO_INTERNAL;
void mono_gc_free_fixed (void* addr) MONO_INTERNAL;
/* make sure the gchandle was allocated for an object in domain */
gboolean mono_gchandle_is_in_domain (guint32 gchandle, MonoDomain *domain) MONO_INTERNAL;
void mono_gchandle_free_domain (MonoDomain *domain) MONO_INTERNAL;
typedef void (*FinalizerThreadCallback) (gpointer user_data);
/* if there are finalizers to run, run them. Returns the number of finalizers run */
gboolean mono_gc_pending_finalizers (void) MONO_INTERNAL;
void mono_gc_finalize_notify (void) MONO_INTERNAL;
void* mono_gc_alloc_pinned_obj (MonoVTable *vtable, size_t size) MONO_INTERNAL;
void* mono_gc_alloc_obj (MonoVTable *vtable, size_t size) MONO_INTERNAL;
void* mono_gc_alloc_vector (MonoVTable *vtable, size_t size, uintptr_t max_length) MONO_INTERNAL;
void* mono_gc_alloc_array (MonoVTable *vtable, size_t size, uintptr_t max_length, uintptr_t bounds_size) MONO_INTERNAL;
void* mono_gc_alloc_string (MonoVTable *vtable, size_t size, gint32 len) MONO_INTERNAL;
void* mono_gc_make_descr_for_string (gsize *bitmap, int numbits) MONO_INTERNAL;
void* mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size) MONO_INTERNAL;
void* mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size) MONO_INTERNAL;
void mono_gc_register_for_finalization (MonoObject *obj, void *user_data) MONO_INTERNAL;
void mono_gc_add_memory_pressure (gint64 value) MONO_INTERNAL;
int mono_gc_register_root (char *start, size_t size, void *descr) MONO_INTERNAL;
void mono_gc_deregister_root (char* addr) MONO_INTERNAL;
int mono_gc_finalizers_for_domain (MonoDomain *domain, MonoObject **out_array, int out_size) MONO_INTERNAL;
void mono_gc_run_finalize (void *obj, void *data) MONO_INTERNAL;
void mono_gc_clear_domain (MonoDomain * domain) MONO_INTERNAL;
void* mono_gc_alloc_mature (MonoVTable *vtable) MONO_INTERNAL;
/*
* Register a root which can only be written using a write barrier.
* Writes to the root must be done using a write barrier (MONO_ROOT_SETREF).
* If the root uses an user defined mark routine, the writes are not required to be
* to the area between START and START+SIZE.
* The write barrier allows the GC to avoid scanning this root at each collection, so it
* is more efficient.
* FIXME: Add an API for clearing remset entries if a root with a user defined
* mark routine is deleted.
*/
int mono_gc_register_root_wbarrier (char *start, size_t size, void *descr) MONO_INTERNAL;
void mono_gc_wbarrier_set_root (gpointer ptr, MonoObject *value) MONO_INTERNAL;
/* Set a field of a root registered using mono_gc_register_root_wbarrier () */
#define MONO_ROOT_SETREF(s,fieldname,value) do { \
mono_gc_wbarrier_set_root (&((s)->fieldname), (MonoObject*)value); \
} while (0)
void mono_gc_finalize_threadpool_threads (void) MONO_INTERNAL;
/* fast allocation support */
/* Accessible using mono_marshal_wrapper_info_from_wrapper () */
typedef struct {
const char *gc_name;
int alloc_type;
} AllocatorWrapperInfo;
MonoMethod* mono_gc_get_managed_allocator (MonoVTable *vtable, gboolean for_box) MONO_INTERNAL;
MonoMethod* mono_gc_get_managed_array_allocator (MonoVTable *vtable, int rank) MONO_INTERNAL;
MonoMethod *mono_gc_get_managed_allocator_by_type (int atype) MONO_INTERNAL;
guint32 mono_gc_get_managed_allocator_types (void) MONO_INTERNAL;
/* Return a short string identifying the GC, indented to be saved in AOT images */
const char *mono_gc_get_gc_name (void) MONO_INTERNAL;
/* Fast write barriers */
MonoMethod* mono_gc_get_write_barrier (void) MONO_INTERNAL;
/* Fast valuetype copy */
void mono_gc_wbarrier_value_copy_bitmap (gpointer dest, gpointer src, int size, unsigned bitmap) MONO_INTERNAL;
/* helper for the managed alloc support */
MonoString *mono_string_alloc (int length) MONO_INTERNAL;
/*
* Functions supplied by the runtime and called by the GC. Currently only used
* by SGEN.
*/
typedef struct {
/*
* Function called during thread startup/attach to allocate thread-local data
* needed by the other functions.
*/
gpointer (*thread_attach_func) (void);
/*
* Function called during thread deatch to free the data allocated by
* thread_attach_func.
*/
void (*thread_detach_func) (gpointer user_data);
/*
* Function called from every thread when suspending for GC. It can save
* data needed for marking from thread stacks. user_data is the data returned
* by attach_func. This might called with GC locks held and the word stopped,
* so it shouldn't do any synchronization etc.
*/
void (*thread_suspend_func) (gpointer user_data, void *sigcontext);
/*
* Function called to mark from thread stacks. user_data is the data returned
* by attach_func. This is called twice, with the word stopped:
* - in the first pass, it should mark areas of the stack using
* conservative marking by calling mono_gc_conservatively_scan_area ().
* - in the second pass, it should mark the remaining areas of the stack
* using precise marking by calling mono_gc_scan_object ().
*/
void (*thread_mark_func) (gpointer user_data, guint8 *stack_start, guint8 *stack_end, gboolean precise);
} MonoGCCallbacks;
/* Set the callback functions callable by the GC */
void mono_gc_set_gc_callbacks (MonoGCCallbacks *callbacks) MONO_INTERNAL;
MonoGCCallbacks *mono_gc_get_gc_callbacks (void) MONO_INTERNAL;
/* Functions callable from the thread mark func */
/* Scan the memory area between START and END conservatively */
void mono_gc_conservatively_scan_area (void *start, void *end) MONO_INTERNAL;
/* Scan OBJ, returning its new address */
void *mono_gc_scan_object (void *obj) MONO_INTERNAL;
/* Return the bitmap encoded by a descriptor */
gsize* mono_gc_get_bitmap_for_descr (void *descr, int *numbits) MONO_INTERNAL;
/* Return the suspend signal number used by the GC to suspend threads,
or -1 if not applicable. */
int mono_gc_get_suspend_signal (void) MONO_INTERNAL;
/*
* Return a human readable description of the GC in malloc-ed memory.
*/
char* mono_gc_get_description (void) MONO_INTERNAL;
/*
* Configure the GC to desktop mode
*/
void mono_gc_set_desktop_mode (void) MONO_INTERNAL;
/*
* Return whenever this GC can move objects
*/
gboolean mono_gc_is_moving (void) MONO_INTERNAL;
typedef void* (*MonoGCLockedCallbackFunc) (void *data);
void* mono_gc_invoke_with_gc_lock (MonoGCLockedCallbackFunc func, void *data) MONO_INTERNAL;
int mono_gc_get_los_limit (void) MONO_INTERNAL;
guint8* mono_gc_get_card_table (int *shift_bits, gpointer *card_mask) MONO_INTERNAL;
void* mono_gc_get_nursery (int *shift_bits, size_t *size) MONO_INTERNAL;
void mono_gc_set_skip_thread (gboolean skip) MONO_INTERNAL;
/*
* Return whenever GC is disabled
*/
gboolean mono_gc_is_disabled (void) MONO_INTERNAL;
#if defined(__MACH__)
void mono_gc_register_mach_exception_thread (pthread_t thread) MONO_INTERNAL;
pthread_t mono_gc_get_mach_exception_thread (void) MONO_INTERNAL;
#endif
gboolean mono_gc_parse_environment_string_extract_number (const char *str, glong *out) MONO_INTERNAL;
gboolean mono_gc_precise_stack_mark_enabled (void) MONO_INTERNAL;
FILE *mono_gc_get_logfile (void) MONO_INTERNAL;
typedef void (*mono_reference_queue_callback) (void *user_data);
typedef struct _MonoReferenceQueue MonoReferenceQueue;
typedef struct _RefQueueEntry RefQueueEntry;
struct _RefQueueEntry {
#ifdef HAVE_SGEN_GC
void *dis_link;
#else
guint32 gchandle;
#endif
MonoDomain *domain;
void *user_data;
RefQueueEntry *next;
};
struct _MonoReferenceQueue {
RefQueueEntry *queue;
mono_reference_queue_callback callback;
MonoReferenceQueue *next;
gboolean should_be_deleted;
};
MonoReferenceQueue* mono_gc_reference_queue_new (mono_reference_queue_callback callback) MONO_INTERNAL;
void mono_gc_reference_queue_free (MonoReferenceQueue *queue) MONO_INTERNAL;
gboolean mono_gc_reference_queue_add (MonoReferenceQueue *queue, MonoObject *obj, void *user_data) MONO_INTERNAL;
void mono_gc_bzero (void *dest, size_t size) MONO_INTERNAL;
void mono_gc_memmove (void *dest, const void *src, size_t size) MONO_INTERNAL;
guint mono_gc_get_vtable_bits (MonoClass *class) MONO_INTERNAL;
#endif /* __MONO_METADATA_GC_INTERNAL_H__ */