[debugger] Ports from dotnet/runtime to maintain compatibility (#21653)
[mono-project.git] / mono / metadata / sgen-client-mono.h
blobf69e05904f6df481021488aca2b95a685e5f357f
1 /**
2 * \file
3 * Mono's client definitions for SGen.
5 * Copyright (C) 2014 Xamarin Inc
7 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8 */
10 #ifdef SGEN_DEFINE_OBJECT_VTABLE
12 #include "sgen/sgen-archdep.h"
13 #include "utils/mono-threads.h"
14 #include "utils/mono-mmap.h"
15 #include "metadata/object-internals.h"
17 typedef MonoObject GCObject;
18 typedef MonoVTable* GCVTable;
20 static inline GCVTable
21 SGEN_LOAD_VTABLE_UNCHECKED (GCObject *obj)
23 return obj->vtable;
26 static inline SgenDescriptor
27 sgen_vtable_get_descriptor (GCVTable vtable)
29 return (SgenDescriptor)vtable->gc_descr;
32 typedef struct _SgenClientThreadInfo SgenClientThreadInfo;
33 struct _SgenClientThreadInfo {
34 MonoThreadInfo info;
37 * `skip` is set to TRUE when STW fails to suspend a thread, most probably because
38 * the underlying thread is dead.
40 gboolean skip, suspend_done;
41 volatile int in_critical_region;
43 #ifdef SGEN_POSIX_STW
44 /* This is -1 until the first suspend. */
45 int signal;
46 /* FIXME: kill this, we only use signals on systems that have rt-posix, which doesn't have issues with duplicates. */
47 unsigned int stop_count; /* to catch duplicate signals. */
48 #endif
50 gpointer runtime_data;
52 void *stack_end;
53 void *stack_start;
54 void *stack_start_limit;
56 MonoContext ctx; /* ditto */
59 #else
61 #include "metadata/profiler-private.h"
62 #include "utils/dtrace.h"
63 #include "utils/mono-counters.h"
64 #include "utils/mono-logger-internals.h"
65 #include "utils/mono-time.h"
66 #include "utils/mono-os-semaphore.h"
67 #include "metadata/sgen-bridge-internals.h"
69 extern void mono_sgen_register_moved_object (void *obj, void *destination);
70 extern void mono_sgen_gc_event_moves (void);
71 extern void mono_sgen_gc_event_resize (void);
73 extern void mono_sgen_init_stw (void);
75 enum {
76 INTERNAL_MEM_EPHEMERON_LINK = INTERNAL_MEM_FIRST_CLIENT,
77 INTERNAL_MEM_MOVED_OBJECT,
78 INTERNAL_MEM_MAX
81 static inline mword
82 sgen_mono_array_size (GCVTable vtable, MonoArray *array, mword *bounds_size, mword descr)
84 mword size, size_without_bounds;
85 int element_size;
87 if ((descr & DESC_TYPE_MASK) == DESC_TYPE_VECTOR)
88 element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
89 else
90 element_size = m_class_get_sizes (vtable->klass).element_size;
92 size_without_bounds = size = MONO_SIZEOF_MONO_ARRAY + (mword)element_size * mono_array_length_internal (array);
94 if (G_UNLIKELY (array->bounds)) {
95 size += sizeof (mono_array_size_t) - 1;
96 size &= ~(sizeof (mono_array_size_t) - 1);
97 size += sizeof (MonoArrayBounds) * m_class_get_rank (vtable->klass);
100 if (bounds_size)
101 *bounds_size = size - size_without_bounds;
102 return size;
105 #define SGEN_CLIENT_OBJECT_HEADER_SIZE (sizeof (GCObject))
106 #define SGEN_CLIENT_MINIMUM_OBJECT_SIZE SGEN_CLIENT_OBJECT_HEADER_SIZE
108 static mword /*__attribute__ ((__noinline__)) not sure if this hint is a good idea*/
109 sgen_client_slow_object_get_size (GCVTable vtable, GCObject* o)
111 MonoClass *klass = ((MonoVTable*)vtable)->klass;
114 * We depend on mono_string_length_fast and
115 * mono_array_length_internal not using the object's vtable.
117 if (klass == mono_defaults.string_class) {
118 return MONO_SIZEOF_MONO_STRING + 2 * mono_string_length_fast ((MonoString*) o) + 2;
119 } else if (m_class_get_rank (klass)) {
120 return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, 0);
121 } else {
122 /* from a created object: the class must be inited already */
123 return m_class_get_instance_size (klass);
128 * This function can be called on an object whose first word, the
129 * vtable field, is not intact. This is necessary for the parallel
130 * collector.
132 static MONO_NEVER_INLINE mword
133 sgen_client_par_object_get_size (GCVTable vtable, GCObject* o)
135 SgenDescriptor descr = sgen_vtable_get_descriptor (vtable);
136 mword type = descr & DESC_TYPE_MASK;
138 if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_PTRFREE) {
139 mword size = descr & 0xfff8;
140 SGEN_ASSERT (9, size >= sizeof (MonoObject), "Run length object size to small");
141 return size;
142 } else if (descr == SGEN_DESC_STRING) {
143 return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
144 } else if (type == DESC_TYPE_VECTOR) {
145 return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, descr);
148 return sgen_client_slow_object_get_size (vtable, o);
151 static MONO_ALWAYS_INLINE size_t G_GNUC_UNUSED
152 sgen_client_array_element_size (GCVTable gc_vtable)
154 MonoVTable *vt = (MonoVTable*)gc_vtable;
155 return mono_array_element_size (vt->klass);
158 static MONO_ALWAYS_INLINE G_GNUC_UNUSED char*
159 sgen_client_array_data_start (GCObject *obj)
161 return (char*)(obj) + G_STRUCT_OFFSET (MonoArray, vector);
164 static MONO_ALWAYS_INLINE size_t G_GNUC_UNUSED
165 sgen_client_array_length (GCObject *obj)
167 return mono_array_length_internal ((MonoArray*)obj);
170 static MONO_ALWAYS_INLINE gboolean G_GNUC_UNUSED
171 sgen_client_object_is_array_fill (GCObject *o)
173 return ((MonoObject*)o)->synchronisation == GINT_TO_POINTER (-1);
176 static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
177 sgen_client_pre_copy_checks (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
179 MonoVTable *vt = (MonoVTable*)gc_vtable;
180 SGEN_ASSERT (9, m_class_is_inited (vt->klass), "vtable %p for class %s:%s was not initialized", vt, m_class_get_name_space (vt->klass), m_class_get_name (vt->klass));
183 static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
184 sgen_client_update_copied_object (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
186 MonoVTable *vt = (MonoVTable*)gc_vtable;
187 if (G_UNLIKELY (vt->rank && ((MonoArray*)obj)->bounds)) {
188 MonoArray *array = (MonoArray*)destination;
189 array->bounds = (MonoArrayBounds*)((char*)destination + ((char*)((MonoArray*)obj)->bounds - (char*)obj));
190 SGEN_LOG (9, "Array instance %p: size: %lu, rank: %d, length: %lu", array, (unsigned long)objsize, vt->rank, (unsigned long)mono_array_length_internal (array));
193 if (MONO_PROFILER_ENABLED (gc_moves))
194 mono_sgen_register_moved_object (obj, destination);
197 #ifdef XDOMAIN_CHECKS_IN_WBARRIER
198 extern gboolean sgen_mono_xdomain_checks;
200 #define sgen_client_wbarrier_generic_nostore_check(ptr) do { \
201 /* FIXME: ptr_in_heap must be called with the GC lock held */ \
202 if (sgen_mono_xdomain_checks && *(MonoObject**)ptr && ptr_in_heap (ptr)) { \
203 char *start = find_object_for_ptr (ptr); \
204 MonoObject *value = *(MonoObject**)ptr; \
205 LOCK_GC; \
206 SGEN_ASSERT (0, start, "Write barrier outside an object?"); \
207 if (start) { \
208 MonoObject *obj = (MonoObject*)start; \
209 if (obj->vtable->domain != value->vtable->domain) \
210 SGEN_ASSERT (0, is_xdomain_ref_allowed (ptr, start, obj->vtable->domain), "Cross-domain ref not allowed"); \
212 UNLOCK_GC; \
214 } while (0)
215 #else
216 #define sgen_client_wbarrier_generic_nostore_check(ptr)
217 #endif
219 static gboolean G_GNUC_UNUSED
220 sgen_client_object_has_critical_finalizer (GCObject *obj)
222 MonoClass *klass;
224 if (!mono_defaults.critical_finalizer_object)
225 return FALSE;
227 klass = SGEN_LOAD_VTABLE (obj)->klass;
229 return mono_class_has_parent_fast (klass, mono_defaults.critical_finalizer_object);
232 const char* sgen_client_vtable_get_namespace (GCVTable vtable);
233 const char* sgen_client_vtable_get_name (GCVTable vtable);
235 static gboolean G_GNUC_UNUSED
236 sgen_client_bridge_need_processing (void)
238 return sgen_need_bridge_processing ();
241 static void G_GNUC_UNUSED
242 sgen_client_bridge_reset_data (void)
244 sgen_bridge_reset_data ();
247 static void G_GNUC_UNUSED
248 sgen_client_bridge_processing_stw_step (void)
250 sgen_bridge_processing_stw_step ();
253 void
254 mono_gc_wait_for_bridge_processing_internal (void);
256 static void G_GNUC_UNUSED
257 sgen_client_bridge_wait_for_processing (void)
259 mono_gc_wait_for_bridge_processing_internal ();
262 static void G_GNUC_UNUSED
263 sgen_client_bridge_processing_finish (int generation)
265 sgen_bridge_processing_finish (generation);
268 static gboolean G_GNUC_UNUSED
269 sgen_client_bridge_is_bridge_object (GCObject *obj)
271 return sgen_is_bridge_object (obj);
274 static void G_GNUC_UNUSED
275 sgen_client_bridge_register_finalized_object (GCObject *object)
277 sgen_bridge_register_finalized_object (object);
280 static void G_GNUC_UNUSED
281 sgen_client_binary_protocol_collection_requested (int generation, size_t requested_size, gboolean force)
283 MONO_GC_REQUESTED (generation, requested_size, force);
286 void
287 sgen_client_binary_protocol_collection_begin (int minor_gc_count, int generation);
289 void
290 sgen_client_binary_protocol_collection_end (int minor_gc_count, int generation, long long num_objects_scanned, long long num_unique_objects_scanned);
292 static void G_GNUC_UNUSED
293 sgen_client_binary_protocol_concurrent_start (void)
295 MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD);
298 static void G_GNUC_UNUSED
299 sgen_client_binary_protocol_concurrent_update (void)
301 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
304 static void G_GNUC_UNUSED
305 sgen_client_binary_protocol_concurrent_finish (void)
307 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
310 static void G_GNUC_UNUSED
311 sgen_client_binary_protocol_sweep_begin (int generation, int full_sweep)
313 MONO_GC_SWEEP_BEGIN (generation, full_sweep);
316 static void G_GNUC_UNUSED
317 sgen_client_binary_protocol_sweep_end (int generation, int full_sweep)
319 MONO_GC_SWEEP_END (generation, full_sweep);
322 static void G_GNUC_UNUSED
323 sgen_client_binary_protocol_world_stopping (int generation, long long timestamp, gpointer thread)
325 MONO_GC_WORLD_STOP_BEGIN ();
328 static void G_GNUC_UNUSED
329 sgen_client_binary_protocol_world_stopped (int generation, long long timestamp, long long total_major_cards, long long marked_major_cards, long long total_los_cards, long long marked_los_cards)
331 MONO_GC_WORLD_STOP_END ();
334 static void G_GNUC_UNUSED
335 sgen_client_binary_protocol_world_restarting (int generation, long long timestamp, long long total_major_cards, long long marked_major_cards, long long total_los_cards, long long marked_los_cards)
337 MONO_GC_WORLD_RESTART_BEGIN (generation);
340 static void G_GNUC_UNUSED
341 sgen_client_binary_protocol_world_restarted (int generation, long long timestamp)
343 MONO_GC_WORLD_RESTART_END (generation);
346 static void G_GNUC_UNUSED
347 sgen_client_binary_protocol_block_alloc (gpointer addr, size_t size)
351 static void G_GNUC_UNUSED
352 sgen_client_binary_protocol_block_free (gpointer addr, size_t size)
356 static void G_GNUC_UNUSED
357 sgen_client_binary_protocol_block_set_state (gpointer addr, size_t size, int old, int new_)
361 static void G_GNUC_UNUSED
362 sgen_client_binary_protocol_mark_start (int generation)
366 static void G_GNUC_UNUSED
367 sgen_client_binary_protocol_mark_end (int generation)
371 static void G_GNUC_UNUSED
372 sgen_client_binary_protocol_reclaim_start (int generation)
376 static void G_GNUC_UNUSED
377 sgen_client_binary_protocol_reclaim_end (int generation)
381 static void
382 mono_binary_protocol_alloc_generic (gpointer obj, gpointer vtable, size_t size, gboolean pinned)
384 #ifdef ENABLE_DTRACE
385 const char *name_space = sgen_client_vtable_get_namespace ((GCVTable)vtable);
386 const char *name = sgen_client_vtable_get_name ((GCVTable)vtable);
388 if (sgen_ptr_in_nursery (obj)) {
389 if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ()))
390 MONO_GC_NURSERY_OBJ_ALLOC ((mword)obj, size, name_space, name);
391 } else {
392 if (size > SGEN_MAX_SMALL_OBJ_SIZE) {
393 if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()))
394 MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword)obj, size, name_space, name);
395 } else if (pinned) {
396 MONO_GC_MAJOR_OBJ_ALLOC_PINNED ((mword)obj, size, name_space, name);
399 #endif
402 static void G_GNUC_UNUSED
403 sgen_client_binary_protocol_alloc (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
405 mono_binary_protocol_alloc_generic (obj, vtable, size, FALSE);
408 static void G_GNUC_UNUSED
409 sgen_client_binary_protocol_alloc_pinned (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
411 mono_binary_protocol_alloc_generic (obj, vtable, size, TRUE);
414 static void G_GNUC_UNUSED
415 sgen_client_binary_protocol_alloc_degraded (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
417 MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED ((mword)obj, size, sgen_client_vtable_get_namespace ((GCVTable)vtable), sgen_client_vtable_get_name ((GCVTable)vtable));
420 static void G_GNUC_UNUSED
421 sgen_client_binary_protocol_card_scan (gpointer start, size_t size)
425 static void G_GNUC_UNUSED
426 sgen_client_binary_protocol_pin_stage (gpointer addr_ptr, gpointer addr)
430 static void G_GNUC_UNUSED
431 sgen_client_binary_protocol_cement_stage (gpointer addr)
435 static void G_GNUC_UNUSED
436 sgen_client_binary_protocol_pin (gpointer obj, gpointer vtable, size_t size)
438 #ifdef ENABLE_DTRACE
439 if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
440 int gen = sgen_ptr_in_nursery (obj) ? GENERATION_NURSERY : GENERATION_OLD;
441 MONO_GC_OBJ_PINNED ((mword)obj,
442 sgen_safe_object_get_size ((GCObject*)obj),
443 sgen_client_vtable_get_namespace ((GCVTable)vtable), sgen_client_vtable_get_name ((GCVTable)vtable), gen);
445 #endif
448 static void G_GNUC_UNUSED
449 sgen_client_binary_protocol_mark (gpointer obj, gpointer vtable, size_t size)
453 static void G_GNUC_UNUSED
454 sgen_client_binary_protocol_scan_begin (gpointer obj, gpointer vtable, size_t size)
458 static void G_GNUC_UNUSED
459 sgen_client_binary_protocol_scan_vtype_begin (gpointer obj, size_t size)
463 static void G_GNUC_UNUSED
464 sgen_client_binary_protocol_scan_process_reference (gpointer obj, gpointer ptr, gpointer value)
468 static void G_GNUC_UNUSED
469 sgen_client_binary_protocol_scan_stack (gpointer thread, gpointer stack_start, gpointer stack_end, int skip_reason)
473 static void G_GNUC_UNUSED
474 sgen_client_binary_protocol_wbarrier (gpointer ptr, gpointer value, gpointer value_vtable)
478 static void G_GNUC_UNUSED
479 sgen_client_binary_protocol_cement (gpointer ptr, gpointer vtable, size_t size)
481 #ifdef ENABLE_DTRACE
482 if (G_UNLIKELY (MONO_GC_OBJ_CEMENTED_ENABLED())) {
483 MONO_GC_OBJ_CEMENTED ((mword)ptr, sgen_safe_object_get_size ((GCObject*)ptr),
484 sgen_client_vtable_get_namespace ((GCVTable)vtable), sgen_client_vtable_get_name ((GCVTable)vtable));
486 #endif
489 static void G_GNUC_UNUSED
490 sgen_client_binary_protocol_copy (gpointer from, gpointer to, gpointer vtable, size_t size)
492 #ifdef ENABLE_DTRACE
493 if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
494 int dest_gen = sgen_ptr_in_nursery (to) ? GENERATION_NURSERY : GENERATION_OLD;
495 int src_gen = sgen_ptr_in_nursery (from) ? GENERATION_NURSERY : GENERATION_OLD;
496 MONO_GC_OBJ_MOVED ((mword)to, (mword)from, dest_gen, src_gen, size, sgen_client_vtable_get_namespace ((GCVTable)vtable), sgen_client_vtable_get_name ((GCVTable)vtable));
498 #endif
501 static void G_GNUC_UNUSED
502 sgen_client_binary_protocol_global_remset (gpointer ptr, gpointer value, gpointer value_vtable)
504 #ifdef ENABLE_DTRACE
505 if (G_UNLIKELY (MONO_GC_GLOBAL_REMSET_ADD_ENABLED ())) {
506 MONO_GC_GLOBAL_REMSET_ADD ((mword)ptr, (mword)value, sgen_safe_object_get_size ((GCObject*)value),
507 sgen_client_vtable_get_namespace ((GCVTable)value_vtable), sgen_client_vtable_get_name ((GCVTable)value_vtable));
509 #endif
512 static void G_GNUC_UNUSED
513 sgen_client_binary_protocol_mod_union_remset (gpointer obj, gpointer ptr, gpointer value, gpointer value_vtable)
517 static void G_GNUC_UNUSED
518 sgen_client_binary_protocol_ptr_update (gpointer ptr, gpointer old_value, gpointer new_value, gpointer vtable, size_t size)
522 static void G_GNUC_UNUSED
523 sgen_client_binary_protocol_cleanup (gpointer ptr, gpointer vtable, size_t size)
527 static void G_GNUC_UNUSED
528 sgen_client_binary_protocol_dislink_add (gpointer link, gpointer obj, gboolean track)
532 static void G_GNUC_UNUSED
533 sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolean track)
535 #ifdef ENABLE_DTRACE
536 if (MONO_GC_WEAK_UPDATE_ENABLED ()) {
537 GCVTable vt = obj ? SGEN_LOAD_VTABLE (obj) : NULL;
538 MONO_GC_WEAK_UPDATE ((mword)link,
539 (mword)obj,
540 obj ? sgen_safe_object_get_size ((GCObject*)obj) : 0u,
541 obj ? sgen_client_vtable_get_namespace (vt) : NULL,
542 obj ? sgen_client_vtable_get_name (vt) : NULL,
543 track ? 1 : 0);
545 #endif
548 static void G_GNUC_UNUSED
549 sgen_client_binary_protocol_dislink_remove (gpointer link, gboolean track)
553 static void G_GNUC_UNUSED
554 sgen_client_binary_protocol_empty (gpointer start, size_t size)
556 if (sgen_ptr_in_nursery (start))
557 MONO_GC_NURSERY_SWEPT ((mword)start, size);
558 else
559 MONO_GC_MAJOR_SWEPT ((mword)start, size);
562 static void G_GNUC_UNUSED
563 sgen_client_binary_protocol_thread_suspend (gpointer thread, gpointer stopped_ip)
567 static void G_GNUC_UNUSED
568 sgen_client_binary_protocol_thread_restart (gpointer thread)
572 static void G_GNUC_UNUSED
573 sgen_client_binary_protocol_thread_register (gpointer thread)
577 static void G_GNUC_UNUSED
578 sgen_client_binary_protocol_thread_unregister (gpointer thread)
582 static void G_GNUC_UNUSED
583 sgen_client_binary_protocol_missing_remset (gpointer obj, gpointer obj_vtable, int offset, gpointer value, gpointer value_vtable, gboolean value_pinned)
587 static void G_GNUC_UNUSED
588 sgen_client_binary_protocol_cement_reset (void)
592 static void G_GNUC_UNUSED
593 sgen_client_binary_protocol_domain_unload_begin (gpointer domain)
597 static void G_GNUC_UNUSED
598 sgen_client_binary_protocol_domain_unload_end (gpointer domain)
602 static void G_GNUC_UNUSED
603 sgen_client_binary_protocol_gray_enqueue (gpointer queue, gpointer cursor, gpointer value)
607 static void G_GNUC_UNUSED
608 sgen_client_binary_protocol_gray_dequeue (gpointer queue, gpointer cursor, gpointer value)
612 static void G_GNUC_UNUSED
613 sgen_client_binary_protocol_major_card_table_scan_start (long long timestamp, gboolean mod_union)
617 static void G_GNUC_UNUSED
618 sgen_client_binary_protocol_major_card_table_scan_end (long long timestamp, gboolean mod_union)
622 static void G_GNUC_UNUSED
623 sgen_client_binary_protocol_los_card_table_scan_start (long long timestamp, gboolean mod_union)
627 static void G_GNUC_UNUSED
628 sgen_client_binary_protocol_los_card_table_scan_end (long long timestamp, gboolean mod_union)
632 static void G_GNUC_UNUSED
633 sgen_client_binary_protocol_finish_gray_stack_start (long long timestamp, int generation)
637 static void G_GNUC_UNUSED
638 sgen_client_binary_protocol_finish_gray_stack_end (long long timestamp, int generation)
642 static void G_GNUC_UNUSED
643 sgen_client_binary_protocol_worker_finish (long long timestamp, gboolean forced)
647 static void G_GNUC_UNUSED
648 sgen_client_binary_protocol_evacuating_blocks (size_t block_size)
652 static void G_GNUC_UNUSED
653 sgen_client_binary_protocol_concurrent_sweep_end (long long timestamp)
657 static void G_GNUC_UNUSED
658 sgen_client_binary_protocol_header (long long check, int version, int ptr_size, gboolean little_endian)
662 static void G_GNUC_UNUSED
663 sgen_client_binary_protocol_pin_stats (int objects_pinned_in_nursery, size_t bytes_pinned_in_nursery, int objects_pinned_in_major, size_t bytes_pinned_in_major)
667 static void G_GNUC_UNUSED
668 sgen_client_root_registered (char *start, size_t size, MonoGCRootSource source, void *key, const char *msg)
670 MONO_PROFILER_RAISE (gc_root_register, ((const mono_byte *) start, size, source, key, msg));
673 static void G_GNUC_UNUSED
674 sgen_client_root_deregistered (char *start)
676 MONO_PROFILER_RAISE (gc_root_unregister, ((const mono_byte *) start));
679 static void G_GNUC_UNUSED
680 sgen_client_binary_protocol_worker_finish_stats (int worker_index, int generation, gboolean forced, long long major_scan, long long los_scan, long long work_time)
684 static void G_GNUC_UNUSED
685 sgen_client_binary_protocol_collection_end_stats (long long major_scan, long long los_scan, long long finish_stack)
689 static void G_GNUC_UNUSED
690 sgen_client_binary_protocol_ephemeron_ref (gpointer list, gpointer key, gpointer val)
694 #define TLAB_ACCESS_INIT SgenThreadInfo *__thread_info__ = mono_tls_get_sgen_thread_info ()
695 #define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
697 /* Enter must be visible before anything is done in the critical region. */
698 #define ENTER_CRITICAL_REGION do { mono_atomic_store_acquire (&IN_CRITICAL_REGION, 1); } while (0)
700 /* Exit must make sure all critical regions stores are visible before it signal the end of the region.
701 * We don't need to emit a full barrier since we
703 #define EXIT_CRITICAL_REGION do { mono_atomic_store_release (&IN_CRITICAL_REGION, 0); } while (0)
705 #ifndef DISABLE_CRITICAL_REGION
707 * We can only use a critical region in the managed allocator if the JIT supports OP_ATOMIC_STORE_I4.
709 * TODO: Query the JIT instead of this ifdef hack.
711 #if defined (TARGET_X86) || defined (TARGET_AMD64) || (defined (TARGET_ARM) && defined (HAVE_ARMV7)) || defined (TARGET_ARM64) || defined (TARGET_RISCV)
712 #define MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
713 #endif
714 #endif
716 #define SGEN_TV_DECLARE(name) gint64 name
717 #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
718 #define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
720 guint64 mono_time_since_last_stw (void);
722 gboolean sgen_has_critical_method (void);
723 gboolean sgen_is_critical_method (MonoMethod *method);
725 void sgen_set_use_managed_allocator (gboolean flag);
726 gboolean sgen_is_managed_allocator (MonoMethod *method);
727 gboolean sgen_has_managed_allocator (void);
728 void sgen_disable_native_stack_scan (void);
730 void sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type);
731 void sgen_null_links_for_domain (MonoDomain *domain);
733 #endif