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.
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
)
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
{
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
;
44 /* This is -1 until the first suspend. */
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. */
50 gpointer runtime_data
;
54 void *stack_start_limit
;
56 MonoContext ctx
; /* ditto */
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);
76 INTERNAL_MEM_EPHEMERON_LINK
= INTERNAL_MEM_FIRST_CLIENT
,
77 INTERNAL_MEM_MOVED_OBJECT
,
82 sgen_mono_array_size (GCVTable vtable
, MonoArray
*array
, mword
*bounds_size
, mword descr
)
84 mword size
, size_without_bounds
;
87 if ((descr
& DESC_TYPE_MASK
) == DESC_TYPE_VECTOR
)
88 element_size
= ((descr
) >> VECTOR_ELSIZE_SHIFT
) & MAX_ELEMENT_SIZE
;
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
);
101 *bounds_size
= size
- size_without_bounds
;
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);
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
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");
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; \
206 SGEN_ASSERT (0, start, "Write barrier outside an object?"); \
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"); \
216 #define sgen_client_wbarrier_generic_nostore_check(ptr)
219 static gboolean G_GNUC_UNUSED
220 sgen_client_object_has_critical_finalizer (GCObject
*obj
)
224 if (!mono_defaults
.critical_finalizer_object
)
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 static void G_GNUC_UNUSED
254 sgen_client_bridge_wait_for_processing (void)
256 mono_gc_wait_for_bridge_processing ();
259 static void G_GNUC_UNUSED
260 sgen_client_bridge_processing_finish (int generation
)
262 sgen_bridge_processing_finish (generation
);
265 static gboolean G_GNUC_UNUSED
266 sgen_client_bridge_is_bridge_object (GCObject
*obj
)
268 return sgen_is_bridge_object (obj
);
271 static void G_GNUC_UNUSED
272 sgen_client_bridge_register_finalized_object (GCObject
*object
)
274 sgen_bridge_register_finalized_object (object
);
277 static void G_GNUC_UNUSED
278 sgen_client_binary_protocol_collection_requested (int generation
, size_t requested_size
, gboolean force
)
280 MONO_GC_REQUESTED (generation
, requested_size
, force
);
284 sgen_client_binary_protocol_collection_begin (int minor_gc_count
, int generation
);
287 sgen_client_binary_protocol_collection_end (int minor_gc_count
, int generation
, long long num_objects_scanned
, long long num_unique_objects_scanned
);
289 static void G_GNUC_UNUSED
290 sgen_client_binary_protocol_concurrent_start (void)
292 MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD
);
295 static void G_GNUC_UNUSED
296 sgen_client_binary_protocol_concurrent_update (void)
298 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD
, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
301 static void G_GNUC_UNUSED
302 sgen_client_binary_protocol_concurrent_finish (void)
304 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD
, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
307 static void G_GNUC_UNUSED
308 sgen_client_binary_protocol_sweep_begin (int generation
, int full_sweep
)
310 MONO_GC_SWEEP_BEGIN (generation
, full_sweep
);
313 static void G_GNUC_UNUSED
314 sgen_client_binary_protocol_sweep_end (int generation
, int full_sweep
)
316 MONO_GC_SWEEP_END (generation
, full_sweep
);
319 static void G_GNUC_UNUSED
320 sgen_client_binary_protocol_world_stopping (int generation
, long long timestamp
, gpointer thread
)
322 MONO_GC_WORLD_STOP_BEGIN ();
325 static void G_GNUC_UNUSED
326 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
)
328 MONO_GC_WORLD_STOP_END ();
331 static void G_GNUC_UNUSED
332 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
)
334 MONO_GC_WORLD_RESTART_BEGIN (generation
);
337 static void G_GNUC_UNUSED
338 sgen_client_binary_protocol_world_restarted (int generation
, long long timestamp
)
340 MONO_GC_WORLD_RESTART_END (generation
);
343 static void G_GNUC_UNUSED
344 sgen_client_binary_protocol_block_alloc (gpointer addr
, size_t size
)
348 static void G_GNUC_UNUSED
349 sgen_client_binary_protocol_block_free (gpointer addr
, size_t size
)
353 static void G_GNUC_UNUSED
354 sgen_client_binary_protocol_block_set_state (gpointer addr
, size_t size
, int old
, int new_
)
358 static void G_GNUC_UNUSED
359 sgen_client_binary_protocol_mark_start (int generation
)
363 static void G_GNUC_UNUSED
364 sgen_client_binary_protocol_mark_end (int generation
)
368 static void G_GNUC_UNUSED
369 sgen_client_binary_protocol_reclaim_start (int generation
)
373 static void G_GNUC_UNUSED
374 sgen_client_binary_protocol_reclaim_end (int generation
)
379 mono_binary_protocol_alloc_generic (gpointer obj
, gpointer vtable
, size_t size
, gboolean pinned
)
382 const char *name_space
= sgen_client_vtable_get_namespace ((GCVTable
)vtable
);
383 const char *name
= sgen_client_vtable_get_name ((GCVTable
)vtable
);
385 if (sgen_ptr_in_nursery (obj
)) {
386 if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ()))
387 MONO_GC_NURSERY_OBJ_ALLOC ((mword
)obj
, size
, name_space
, name
);
389 if (size
> SGEN_MAX_SMALL_OBJ_SIZE
) {
390 if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()))
391 MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword
)obj
, size
, name_space
, name
);
393 MONO_GC_MAJOR_OBJ_ALLOC_PINNED ((mword
)obj
, size
, name_space
, name
);
399 static void G_GNUC_UNUSED
400 sgen_client_binary_protocol_alloc (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
402 mono_binary_protocol_alloc_generic (obj
, vtable
, size
, FALSE
);
405 static void G_GNUC_UNUSED
406 sgen_client_binary_protocol_alloc_pinned (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
408 mono_binary_protocol_alloc_generic (obj
, vtable
, size
, TRUE
);
411 static void G_GNUC_UNUSED
412 sgen_client_binary_protocol_alloc_degraded (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
414 MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED ((mword
)obj
, size
, sgen_client_vtable_get_namespace ((GCVTable
)vtable
), sgen_client_vtable_get_name ((GCVTable
)vtable
));
417 static void G_GNUC_UNUSED
418 sgen_client_binary_protocol_card_scan (gpointer start
, size_t size
)
422 static void G_GNUC_UNUSED
423 sgen_client_binary_protocol_pin_stage (gpointer addr_ptr
, gpointer addr
)
427 static void G_GNUC_UNUSED
428 sgen_client_binary_protocol_cement_stage (gpointer addr
)
432 static void G_GNUC_UNUSED
433 sgen_client_binary_protocol_pin (gpointer obj
, gpointer vtable
, size_t size
)
436 if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
437 int gen
= sgen_ptr_in_nursery (obj
) ? GENERATION_NURSERY
: GENERATION_OLD
;
438 MONO_GC_OBJ_PINNED ((mword
)obj
,
439 sgen_safe_object_get_size ((GCObject
*)obj
),
440 sgen_client_vtable_get_namespace ((GCVTable
)vtable
), sgen_client_vtable_get_name ((GCVTable
)vtable
), gen
);
445 static void G_GNUC_UNUSED
446 sgen_client_binary_protocol_mark (gpointer obj
, gpointer vtable
, size_t size
)
450 static void G_GNUC_UNUSED
451 sgen_client_binary_protocol_scan_begin (gpointer obj
, gpointer vtable
, size_t size
)
455 static void G_GNUC_UNUSED
456 sgen_client_binary_protocol_scan_vtype_begin (gpointer obj
, size_t size
)
460 static void G_GNUC_UNUSED
461 sgen_client_binary_protocol_scan_process_reference (gpointer obj
, gpointer ptr
, gpointer value
)
465 static void G_GNUC_UNUSED
466 sgen_client_binary_protocol_scan_stack (gpointer thread
, gpointer stack_start
, gpointer stack_end
, int skip_reason
)
470 static void G_GNUC_UNUSED
471 sgen_client_binary_protocol_wbarrier (gpointer ptr
, gpointer value
, gpointer value_vtable
)
475 static void G_GNUC_UNUSED
476 sgen_client_binary_protocol_cement (gpointer ptr
, gpointer vtable
, size_t size
)
479 if (G_UNLIKELY (MONO_GC_OBJ_CEMENTED_ENABLED())) {
480 MONO_GC_OBJ_CEMENTED ((mword
)ptr
, sgen_safe_object_get_size ((GCObject
*)ptr
),
481 sgen_client_vtable_get_namespace ((GCVTable
)vtable
), sgen_client_vtable_get_name ((GCVTable
)vtable
));
486 static void G_GNUC_UNUSED
487 sgen_client_binary_protocol_copy (gpointer from
, gpointer to
, gpointer vtable
, size_t size
)
490 if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
491 int dest_gen
= sgen_ptr_in_nursery (to
) ? GENERATION_NURSERY
: GENERATION_OLD
;
492 int src_gen
= sgen_ptr_in_nursery (from
) ? GENERATION_NURSERY
: GENERATION_OLD
;
493 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 static void G_GNUC_UNUSED
499 sgen_client_binary_protocol_global_remset (gpointer ptr
, gpointer value
, gpointer value_vtable
)
502 if (G_UNLIKELY (MONO_GC_GLOBAL_REMSET_ADD_ENABLED ())) {
503 MONO_GC_GLOBAL_REMSET_ADD ((mword
)ptr
, (mword
)value
, sgen_safe_object_get_size ((GCObject
*)value
),
504 sgen_client_vtable_get_namespace ((GCVTable
)value_vtable
), sgen_client_vtable_get_name ((GCVTable
)value_vtable
));
509 static void G_GNUC_UNUSED
510 sgen_client_binary_protocol_mod_union_remset (gpointer obj
, gpointer ptr
, gpointer value
, gpointer value_vtable
)
514 static void G_GNUC_UNUSED
515 sgen_client_binary_protocol_ptr_update (gpointer ptr
, gpointer old_value
, gpointer new_value
, gpointer vtable
, size_t size
)
519 static void G_GNUC_UNUSED
520 sgen_client_binary_protocol_cleanup (gpointer ptr
, gpointer vtable
, size_t size
)
524 static void G_GNUC_UNUSED
525 sgen_client_binary_protocol_dislink_add (gpointer link
, gpointer obj
, gboolean track
)
529 static void G_GNUC_UNUSED
530 sgen_client_binary_protocol_dislink_update (gpointer link
, gpointer obj
, gboolean track
)
533 if (MONO_GC_WEAK_UPDATE_ENABLED ()) {
534 GCVTable vt
= obj
? SGEN_LOAD_VTABLE (obj
) : NULL
;
535 MONO_GC_WEAK_UPDATE ((mword
)link
,
537 obj
? sgen_safe_object_get_size ((GCObject
*)obj
) : 0u,
538 obj
? sgen_client_vtable_get_namespace (vt
) : NULL
,
539 obj
? sgen_client_vtable_get_name (vt
) : NULL
,
545 static void G_GNUC_UNUSED
546 sgen_client_binary_protocol_dislink_remove (gpointer link
, gboolean track
)
550 static void G_GNUC_UNUSED
551 sgen_client_binary_protocol_empty (gpointer start
, size_t size
)
553 if (sgen_ptr_in_nursery (start
))
554 MONO_GC_NURSERY_SWEPT ((mword
)start
, size
);
556 MONO_GC_MAJOR_SWEPT ((mword
)start
, size
);
559 static void G_GNUC_UNUSED
560 sgen_client_binary_protocol_thread_suspend (gpointer thread
, gpointer stopped_ip
)
564 static void G_GNUC_UNUSED
565 sgen_client_binary_protocol_thread_restart (gpointer thread
)
569 static void G_GNUC_UNUSED
570 sgen_client_binary_protocol_thread_register (gpointer thread
)
574 static void G_GNUC_UNUSED
575 sgen_client_binary_protocol_thread_unregister (gpointer thread
)
579 static void G_GNUC_UNUSED
580 sgen_client_binary_protocol_missing_remset (gpointer obj
, gpointer obj_vtable
, int offset
, gpointer value
, gpointer value_vtable
, gboolean value_pinned
)
584 static void G_GNUC_UNUSED
585 sgen_client_binary_protocol_cement_reset (void)
589 static void G_GNUC_UNUSED
590 sgen_client_binary_protocol_domain_unload_begin (gpointer domain
)
594 static void G_GNUC_UNUSED
595 sgen_client_binary_protocol_domain_unload_end (gpointer domain
)
599 static void G_GNUC_UNUSED
600 sgen_client_binary_protocol_gray_enqueue (gpointer queue
, gpointer cursor
, gpointer value
)
604 static void G_GNUC_UNUSED
605 sgen_client_binary_protocol_gray_dequeue (gpointer queue
, gpointer cursor
, gpointer value
)
609 static void G_GNUC_UNUSED
610 sgen_client_binary_protocol_major_card_table_scan_start (long long timestamp
, gboolean mod_union
)
614 static void G_GNUC_UNUSED
615 sgen_client_binary_protocol_major_card_table_scan_end (long long timestamp
, gboolean mod_union
)
619 static void G_GNUC_UNUSED
620 sgen_client_binary_protocol_los_card_table_scan_start (long long timestamp
, gboolean mod_union
)
624 static void G_GNUC_UNUSED
625 sgen_client_binary_protocol_los_card_table_scan_end (long long timestamp
, gboolean mod_union
)
629 static void G_GNUC_UNUSED
630 sgen_client_binary_protocol_finish_gray_stack_start (long long timestamp
, int generation
)
634 static void G_GNUC_UNUSED
635 sgen_client_binary_protocol_finish_gray_stack_end (long long timestamp
, int generation
)
639 static void G_GNUC_UNUSED
640 sgen_client_binary_protocol_worker_finish (long long timestamp
, gboolean forced
)
644 static void G_GNUC_UNUSED
645 sgen_client_binary_protocol_evacuating_blocks (size_t block_size
)
649 static void G_GNUC_UNUSED
650 sgen_client_binary_protocol_concurrent_sweep_end (long long timestamp
)
654 static void G_GNUC_UNUSED
655 sgen_client_binary_protocol_header (long long check
, int version
, int ptr_size
, gboolean little_endian
)
659 static void G_GNUC_UNUSED
660 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
)
664 static void G_GNUC_UNUSED
665 sgen_client_root_registered (char *start
, size_t size
, MonoGCRootSource source
, void *key
, const char *msg
)
667 MONO_PROFILER_RAISE (gc_root_register
, ((const mono_byte
*) start
, size
, source
, key
, msg
));
670 static void G_GNUC_UNUSED
671 sgen_client_root_deregistered (char *start
)
673 MONO_PROFILER_RAISE (gc_root_unregister
, ((const mono_byte
*) start
));
676 static void G_GNUC_UNUSED
677 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
)
681 static void G_GNUC_UNUSED
682 sgen_client_binary_protocol_collection_end_stats (long long major_scan
, long long los_scan
, long long finish_stack
)
686 #define TLAB_ACCESS_INIT SgenThreadInfo *__thread_info__ = mono_tls_get_sgen_thread_info ()
687 #define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
689 /* Enter must be visible before anything is done in the critical region. */
690 #define ENTER_CRITICAL_REGION do { mono_atomic_store_acquire (&IN_CRITICAL_REGION, 1); } while (0)
692 /* Exit must make sure all critical regions stores are visible before it signal the end of the region.
693 * We don't need to emit a full barrier since we
695 #define EXIT_CRITICAL_REGION do { mono_atomic_store_release (&IN_CRITICAL_REGION, 0); } while (0)
697 #ifndef DISABLE_CRITICAL_REGION
699 * We can only use a critical region in the managed allocator if the JIT supports OP_ATOMIC_STORE_I4.
701 * TODO: Query the JIT instead of this ifdef hack.
703 #if defined (TARGET_X86) || defined (TARGET_AMD64) || (defined (TARGET_ARM) && defined (HAVE_ARMV7)) || defined (TARGET_ARM64) || defined (TARGET_RISCV)
704 #define MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
708 #define SGEN_TV_DECLARE(name) gint64 name
709 #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
710 #define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
712 guint64
mono_time_since_last_stw (void);
714 typedef MonoSemType SgenSemaphore
;
716 #define SGEN_SEMAPHORE_INIT(sem,initial) mono_os_sem_init ((sem), (initial))
717 #define SGEN_SEMAPHORE_POST(sem) mono_os_sem_post ((sem))
718 #define SGEN_SEMAPHORE_WAIT(sem) mono_os_sem_wait ((sem), MONO_SEM_FLAGS_NONE)
720 gboolean
sgen_has_critical_method (void);
721 gboolean
sgen_is_critical_method (MonoMethod
*method
);
723 void sgen_set_use_managed_allocator (gboolean flag
);
724 gboolean
sgen_is_managed_allocator (MonoMethod
*method
);
725 gboolean
sgen_has_managed_allocator (void);
727 void sgen_scan_for_registered_roots_in_domain (MonoDomain
*domain
, int root_type
);
728 void sgen_null_links_for_domain (MonoDomain
*domain
);