2 * sgen-client-mono.h: Mono's client definitions for SGen.
4 * Copyright (C) 2014 Xamarin Inc
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License 2.0 as published by the Free Software Foundation;
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License 2.0 along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #ifdef SGEN_DEFINE_OBJECT_VTABLE
22 #include "sgen/sgen-archdep.h"
23 #include "utils/mono-threads.h"
24 #include "utils/mono-mmap.h"
25 #include "metadata/object-internals.h"
27 typedef MonoObject GCObject
;
28 typedef MonoVTable
* GCVTable
;
30 static inline GCVTable
31 SGEN_LOAD_VTABLE_UNCHECKED (GCObject
*obj
)
36 static inline SgenDescriptor
37 sgen_vtable_get_descriptor (GCVTable vtable
)
39 return (SgenDescriptor
)vtable
->gc_descr
;
42 typedef struct _SgenClientThreadInfo SgenClientThreadInfo
;
43 struct _SgenClientThreadInfo
{
47 * `skip` is set to TRUE when STW fails to suspend a thread, most probably because
48 * the underlying thread is dead.
50 gboolean skip
, suspend_done
;
51 volatile int in_critical_region
;
53 gpointer stopped_ip
; /* only valid if the thread is stopped */
54 MonoDomain
*stopped_domain
; /* dsto */
57 This is set the argument of mono_gc_set_skip_thread.
59 A thread that knowingly holds no managed state can call this
60 function around blocking loops to reduce the GC burden by not
66 /* This is -1 until the first suspend. */
68 /* FIXME: kill this, we only use signals on systems that have rt-posix, which doesn't have issues with duplicates. */
69 unsigned int stop_count
; /* to catch duplicate signals. */
72 gpointer runtime_data
;
76 void *stack_start_limit
;
78 /*FIXME pretty please finish killing ARCH_NUM_REGS */
80 MonoContext ctx
; /* ditto */
82 gpointer regs
[ARCH_NUM_REGS
]; /* ditto */
88 #include "metadata/profiler-private.h"
89 #include "utils/dtrace.h"
90 #include "utils/mono-counters.h"
91 #include "utils/mono-logger-internal.h"
92 #include "utils/mono-time.h"
93 #include "utils/mono-semaphore.h"
94 #include "metadata/sgen-bridge-internal.h"
96 extern void mono_sgen_register_moved_object (void *obj
, void *destination
);
97 extern void mono_sgen_gc_event_moves (void);
99 extern void mono_sgen_init_stw (void);
102 INTERNAL_MEM_EPHEMERON_LINK
= INTERNAL_MEM_FIRST_CLIENT
,
107 sgen_mono_array_size (GCVTable vtable
, MonoArray
*array
, mword
*bounds_size
, mword descr
)
109 mword size
, size_without_bounds
;
112 if ((descr
& DESC_TYPE_MASK
) == DESC_TYPE_VECTOR
)
113 element_size
= ((descr
) >> VECTOR_ELSIZE_SHIFT
) & MAX_ELEMENT_SIZE
;
115 element_size
= vtable
->klass
->sizes
.element_size
;
117 size_without_bounds
= size
= sizeof (MonoArray
) + element_size
* mono_array_length_fast (array
);
119 if (G_UNLIKELY (array
->bounds
)) {
120 size
+= sizeof (mono_array_size_t
) - 1;
121 size
&= ~(sizeof (mono_array_size_t
) - 1);
122 size
+= sizeof (MonoArrayBounds
) * vtable
->klass
->rank
;
126 *bounds_size
= size
- size_without_bounds
;
130 #define SGEN_CLIENT_OBJECT_HEADER_SIZE (sizeof (GCObject))
131 #define SGEN_CLIENT_MINIMUM_OBJECT_SIZE SGEN_CLIENT_OBJECT_HEADER_SIZE
133 static mword
/*__attribute__((noinline)) not sure if this hint is a good idea*/
134 sgen_client_slow_object_get_size (GCVTable vtable
, GCObject
* o
)
136 MonoClass
*klass
= ((MonoVTable
*)vtable
)->klass
;
139 * We depend on mono_string_length_fast and
140 * mono_array_length_fast not using the object's vtable.
142 if (klass
== mono_defaults
.string_class
) {
143 return G_STRUCT_OFFSET (MonoString
, chars
) + 2 * mono_string_length_fast ((MonoString
*) o
) + 2;
144 } else if (klass
->rank
) {
145 return sgen_mono_array_size (vtable
, (MonoArray
*)o
, NULL
, 0);
147 /* from a created object: the class must be inited already */
148 return klass
->instance_size
;
153 * This function can be called on an object whose first word, the
154 * vtable field, is not intact. This is necessary for the parallel
157 static MONO_NEVER_INLINE mword
158 sgen_client_par_object_get_size (GCVTable vtable
, GCObject
* o
)
160 SgenDescriptor descr
= sgen_vtable_get_descriptor (vtable
);
161 mword type
= descr
& DESC_TYPE_MASK
;
163 if (type
== DESC_TYPE_RUN_LENGTH
|| type
== DESC_TYPE_SMALL_PTRFREE
) {
164 mword size
= descr
& 0xfff8;
165 SGEN_ASSERT (9, size
>= sizeof (MonoObject
), "Run length object size to small");
167 } else if (descr
== SGEN_DESC_STRING
) {
168 return G_STRUCT_OFFSET (MonoString
, chars
) + 2 * mono_string_length_fast ((MonoString
*) o
) + 2;
169 } else if (type
== DESC_TYPE_VECTOR
) {
170 return sgen_mono_array_size (vtable
, (MonoArray
*)o
, NULL
, descr
);
173 return sgen_client_slow_object_get_size (vtable
, o
);
176 static MONO_ALWAYS_INLINE
size_t G_GNUC_UNUSED
177 sgen_client_array_element_size (GCVTable gc_vtable
)
179 MonoVTable
*vt
= (MonoVTable
*)gc_vtable
;
180 return mono_array_element_size (vt
->klass
);
183 static MONO_ALWAYS_INLINE G_GNUC_UNUSED
char*
184 sgen_client_array_data_start (GCObject
*obj
)
186 return (char*)(obj
) + G_STRUCT_OFFSET (MonoArray
, vector
);
189 static MONO_ALWAYS_INLINE
size_t G_GNUC_UNUSED
190 sgen_client_array_length (GCObject
*obj
)
192 return mono_array_length_fast ((MonoArray
*)obj
);
195 static MONO_ALWAYS_INLINE gboolean G_GNUC_UNUSED
196 sgen_client_object_is_array_fill (GCObject
*o
)
198 return ((MonoObject
*)o
)->synchronisation
== GINT_TO_POINTER (-1);
201 static MONO_ALWAYS_INLINE
void G_GNUC_UNUSED
202 sgen_client_pre_copy_checks (char *destination
, GCVTable gc_vtable
, void *obj
, mword objsize
)
204 MonoVTable
*vt
= (MonoVTable
*)gc_vtable
;
205 SGEN_ASSERT (9, vt
->klass
->inited
, "vtable %p for class %s:%s was not initialized", vt
, vt
->klass
->name_space
, vt
->klass
->name
);
208 static MONO_ALWAYS_INLINE
void G_GNUC_UNUSED
209 sgen_client_update_copied_object (char *destination
, GCVTable gc_vtable
, void *obj
, mword objsize
)
211 MonoVTable
*vt
= (MonoVTable
*)gc_vtable
;
212 if (G_UNLIKELY (vt
->rank
&& ((MonoArray
*)obj
)->bounds
)) {
213 MonoArray
*array
= (MonoArray
*)destination
;
214 array
->bounds
= (MonoArrayBounds
*)((char*)destination
+ ((char*)((MonoArray
*)obj
)->bounds
- (char*)obj
));
215 SGEN_LOG (9, "Array instance %p: size: %lu, rank: %d, length: %lu", array
, (unsigned long)objsize
, vt
->rank
, (unsigned long)mono_array_length (array
));
218 if (G_UNLIKELY (mono_profiler_events
& MONO_PROFILE_GC_MOVES
))
219 mono_sgen_register_moved_object (obj
, destination
);
222 #ifdef XDOMAIN_CHECKS_IN_WBARRIER
223 extern gboolean sgen_mono_xdomain_checks
;
225 #define sgen_client_wbarrier_generic_nostore_check(ptr) do { \
226 /* FIXME: ptr_in_heap must be called with the GC lock held */ \
227 if (sgen_mono_xdomain_checks && *(MonoObject**)ptr && ptr_in_heap (ptr)) { \
228 char *start = find_object_for_ptr (ptr); \
229 MonoObject *value = *(MonoObject**)ptr; \
231 SGEN_ASSERT (0, start, "Write barrier outside an object?"); \
233 MonoObject *obj = (MonoObject*)start; \
234 if (obj->vtable->domain != value->vtable->domain) \
235 SGEN_ASSERT (0, is_xdomain_ref_allowed (ptr, start, obj->vtable->domain), "Cross-domain ref not allowed"); \
241 #define sgen_client_wbarrier_generic_nostore_check(ptr)
244 static gboolean G_GNUC_UNUSED
245 sgen_client_object_has_critical_finalizer (GCObject
*obj
)
249 if (!mono_defaults
.critical_finalizer_object
)
252 class = SGEN_LOAD_VTABLE (obj
)->klass
;
254 return mono_class_has_parent_fast (class, mono_defaults
.critical_finalizer_object
);
257 const char* sgen_client_vtable_get_namespace (GCVTable vtable
);
258 const char* sgen_client_vtable_get_name (GCVTable vtable
);
260 static gboolean G_GNUC_UNUSED
261 sgen_client_bridge_need_processing (void)
263 return sgen_need_bridge_processing ();
266 static void G_GNUC_UNUSED
267 sgen_client_bridge_reset_data (void)
269 sgen_bridge_reset_data ();
272 static void G_GNUC_UNUSED
273 sgen_client_bridge_processing_stw_step (void)
275 sgen_bridge_processing_stw_step ();
278 static void G_GNUC_UNUSED
279 sgen_client_bridge_wait_for_processing (void)
281 mono_gc_wait_for_bridge_processing ();
284 static void G_GNUC_UNUSED
285 sgen_client_bridge_processing_finish (int generation
)
287 sgen_bridge_processing_finish (generation
);
290 static gboolean G_GNUC_UNUSED
291 sgen_client_bridge_is_bridge_object (GCObject
*obj
)
293 return sgen_is_bridge_object (obj
);
296 static void G_GNUC_UNUSED
297 sgen_client_bridge_register_finalized_object (GCObject
*object
)
299 sgen_bridge_register_finalized_object (object
);
302 static void G_GNUC_UNUSED
303 sgen_client_binary_protocol_collection_requested (int generation
, size_t requested_size
, gboolean force
)
305 MONO_GC_REQUESTED (generation
, requested_size
, force
);
308 static void G_GNUC_UNUSED
309 sgen_client_binary_protocol_collection_begin (int minor_gc_count
, int generation
)
311 MONO_GC_BEGIN (generation
);
313 mono_profiler_gc_event (MONO_GC_EVENT_START
, generation
);
315 #ifndef DISABLE_PERFCOUNTERS
316 if (generation
== GENERATION_NURSERY
)
317 mono_perfcounters
->gc_collections0
++;
319 mono_perfcounters
->gc_collections1
++;
323 static void G_GNUC_UNUSED
324 sgen_client_binary_protocol_collection_end (int minor_gc_count
, int generation
, long long num_objects_scanned
, long long num_unique_objects_scanned
)
326 MONO_GC_END (generation
);
328 mono_profiler_gc_event (MONO_GC_EVENT_END
, generation
);
331 static void G_GNUC_UNUSED
332 sgen_client_binary_protocol_concurrent_start (void)
334 MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD
);
337 static void G_GNUC_UNUSED
338 sgen_client_binary_protocol_concurrent_update (void)
340 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD
, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
343 static void G_GNUC_UNUSED
344 sgen_client_binary_protocol_concurrent_finish (void)
346 MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD
, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
349 static void G_GNUC_UNUSED
350 sgen_client_binary_protocol_sweep_begin (int generation
, int full_sweep
)
352 MONO_GC_SWEEP_BEGIN (generation
, full_sweep
);
355 static void G_GNUC_UNUSED
356 sgen_client_binary_protocol_sweep_end (int generation
, int full_sweep
)
358 MONO_GC_SWEEP_END (generation
, full_sweep
);
361 static void G_GNUC_UNUSED
362 sgen_client_binary_protocol_world_stopping (int generation
, long long timestamp
, gpointer thread
)
364 MONO_GC_WORLD_STOP_BEGIN ();
366 mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD
, generation
);
369 static void G_GNUC_UNUSED
370 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
)
372 MONO_GC_WORLD_STOP_END ();
374 mono_profiler_gc_event (MONO_GC_EVENT_POST_STOP_WORLD
, generation
);
377 static void G_GNUC_UNUSED
378 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
)
380 MONO_GC_WORLD_RESTART_BEGIN (generation
);
382 mono_profiler_gc_event (MONO_GC_EVENT_PRE_START_WORLD
, generation
);
385 static void G_GNUC_UNUSED
386 sgen_client_binary_protocol_world_restarted (int generation
, long long timestamp
)
388 MONO_GC_WORLD_RESTART_END (generation
);
390 mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD
, generation
);
393 static void G_GNUC_UNUSED
394 sgen_client_binary_protocol_block_alloc (gpointer addr
, size_t size
)
398 static void G_GNUC_UNUSED
399 sgen_client_binary_protocol_block_free (gpointer addr
, size_t size
)
403 static void G_GNUC_UNUSED
404 sgen_client_binary_protocol_block_set_state (gpointer addr
, size_t size
, int old
, int new)
408 static void G_GNUC_UNUSED
409 sgen_client_binary_protocol_mark_start (int generation
)
411 mono_profiler_gc_event (MONO_GC_EVENT_MARK_START
, generation
);
414 static void G_GNUC_UNUSED
415 sgen_client_binary_protocol_mark_end (int generation
)
417 mono_profiler_gc_event (MONO_GC_EVENT_MARK_END
, generation
);
420 static void G_GNUC_UNUSED
421 sgen_client_binary_protocol_reclaim_start (int generation
)
423 mono_profiler_gc_event (MONO_GC_EVENT_RECLAIM_START
, generation
);
426 static void G_GNUC_UNUSED
427 sgen_client_binary_protocol_reclaim_end (int generation
)
429 mono_profiler_gc_event (MONO_GC_EVENT_RECLAIM_END
, generation
);
433 mono_binary_protocol_alloc_generic (gpointer obj
, gpointer vtable
, size_t size
, gboolean pinned
)
436 const char *namespace = sgen_client_vtable_get_namespace (vtable
);
437 const char *name
= sgen_client_vtable_get_name (vtable
);
439 if (sgen_ptr_in_nursery (obj
)) {
440 if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ()))
441 MONO_GC_NURSERY_OBJ_ALLOC ((mword
)obj
, size
, namespace, name
);
443 if (size
> SGEN_MAX_SMALL_OBJ_SIZE
) {
444 if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()))
445 MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword
)obj
, size
, namespace, name
);
447 MONO_GC_MAJOR_OBJ_ALLOC_PINNED ((mword
)obj
, size
, namespace, name
);
453 static void G_GNUC_UNUSED
454 sgen_client_binary_protocol_alloc (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
456 mono_binary_protocol_alloc_generic (obj
, vtable
, size
, FALSE
);
459 static void G_GNUC_UNUSED
460 sgen_client_binary_protocol_alloc_pinned (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
462 mono_binary_protocol_alloc_generic (obj
, vtable
, size
, TRUE
);
465 static void G_GNUC_UNUSED
466 sgen_client_binary_protocol_alloc_degraded (gpointer obj
, gpointer vtable
, size_t size
, gpointer provenance
)
468 MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED ((mword
)obj
, size
, sgen_client_vtable_get_namespace (vtable
), sgen_client_vtable_get_name (vtable
));
471 static void G_GNUC_UNUSED
472 sgen_client_binary_protocol_card_scan (gpointer start
, size_t size
)
476 static void G_GNUC_UNUSED
477 sgen_client_binary_protocol_pin_stage (gpointer addr_ptr
, gpointer addr
)
481 static void G_GNUC_UNUSED
482 sgen_client_binary_protocol_cement_stage (gpointer addr
)
486 static void G_GNUC_UNUSED
487 sgen_client_binary_protocol_pin (gpointer obj
, gpointer vtable
, size_t size
)
490 if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
491 int gen
= sgen_ptr_in_nursery (obj
) ? GENERATION_NURSERY
: GENERATION_OLD
;
492 MONO_GC_OBJ_PINNED ((mword
)obj
,
493 sgen_safe_object_get_size (obj
),
494 sgen_client_vtable_get_namespace (vtable
), sgen_client_vtable_get_name (vtable
), gen
);
499 static void G_GNUC_UNUSED
500 sgen_client_binary_protocol_mark (gpointer obj
, gpointer vtable
, size_t size
)
504 static void G_GNUC_UNUSED
505 sgen_client_binary_protocol_scan_begin (gpointer obj
, gpointer vtable
, size_t size
)
509 static void G_GNUC_UNUSED
510 sgen_client_binary_protocol_scan_vtype_begin (gpointer obj
, size_t size
)
514 static void G_GNUC_UNUSED
515 sgen_client_binary_protocol_scan_process_reference (gpointer obj
, gpointer ptr
, gpointer value
)
519 static void G_GNUC_UNUSED
520 sgen_client_binary_protocol_scan_stack (gpointer thread
, gpointer stack_start
, gpointer stack_end
, int skip_reason
)
524 static void G_GNUC_UNUSED
525 sgen_client_binary_protocol_wbarrier (gpointer ptr
, gpointer value
, gpointer value_vtable
)
529 static void G_GNUC_UNUSED
530 sgen_client_binary_protocol_cement (gpointer ptr
, gpointer vtable
, size_t size
)
533 if (G_UNLIKELY (MONO_GC_OBJ_CEMENTED_ENABLED())) {
534 MONO_GC_OBJ_CEMENTED ((mword
)ptr
, sgen_safe_object_get_size ((GCObject
*)ptr
),
535 sgen_client_vtable_get_namespace (vtable
), sgen_client_vtable_get_name (vtable
));
540 static void G_GNUC_UNUSED
541 sgen_client_binary_protocol_copy (gpointer from
, gpointer to
, gpointer vtable
, size_t size
)
544 if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
545 int dest_gen
= sgen_ptr_in_nursery (to
) ? GENERATION_NURSERY
: GENERATION_OLD
;
546 int src_gen
= sgen_ptr_in_nursery (from
) ? GENERATION_NURSERY
: GENERATION_OLD
;
547 MONO_GC_OBJ_MOVED ((mword
)to
, (mword
)from
, dest_gen
, src_gen
, size
, sgen_client_vtable_get_namespace (vtable
), sgen_client_vtable_get_name (vtable
));
552 static void G_GNUC_UNUSED
553 sgen_client_binary_protocol_global_remset (gpointer ptr
, gpointer value
, gpointer value_vtable
)
556 if (G_UNLIKELY (MONO_GC_GLOBAL_REMSET_ADD_ENABLED ())) {
557 MONO_GC_GLOBAL_REMSET_ADD ((mword
)ptr
, (mword
)value
, sgen_safe_object_get_size (value
),
558 sgen_client_vtable_get_namespace (value_vtable
), sgen_client_vtable_get_name (value_vtable
));
563 static void G_GNUC_UNUSED
564 sgen_client_binary_protocol_ptr_update (gpointer ptr
, gpointer old_value
, gpointer new_value
, gpointer vtable
, size_t size
)
568 static void G_GNUC_UNUSED
569 sgen_client_binary_protocol_cleanup (gpointer ptr
, gpointer vtable
, size_t size
)
573 static void G_GNUC_UNUSED
574 sgen_client_binary_protocol_dislink_update (gpointer link
, gpointer obj
, gboolean track
, gboolean staged
)
577 if (MONO_GC_WEAK_UPDATE_ENABLED ()) {
578 GCVTable vt
= obj
? SGEN_LOAD_VTABLE (obj
) : NULL
;
579 MONO_GC_WEAK_UPDATE ((mword
)link
,
581 obj
? (mword
)sgen_safe_object_get_size (obj
) : (mword
)0,
582 obj
? sgen_client_vtable_get_namespace (vt
) : NULL
,
583 obj
? sgen_client_vtable_get_name (vt
) : NULL
,
589 static void G_GNUC_UNUSED
590 sgen_client_binary_protocol_dislink_update_staged (gpointer link
, gpointer obj
, gboolean track
, int index
)
594 static void G_GNUC_UNUSED
595 sgen_client_binary_protocol_dislink_process_staged (gpointer link
, gpointer obj
, int index
)
599 static void G_GNUC_UNUSED
600 sgen_client_binary_protocol_empty (gpointer start
, size_t size
)
602 if (sgen_ptr_in_nursery (start
))
603 MONO_GC_NURSERY_SWEPT ((mword
)start
, size
);
605 MONO_GC_MAJOR_SWEPT ((mword
)start
, size
);
608 static void G_GNUC_UNUSED
609 sgen_client_binary_protocol_thread_suspend (gpointer thread
, gpointer stopped_ip
)
613 static void G_GNUC_UNUSED
614 sgen_client_binary_protocol_thread_restart (gpointer thread
)
618 static void G_GNUC_UNUSED
619 sgen_client_binary_protocol_thread_register (gpointer thread
)
623 static void G_GNUC_UNUSED
624 sgen_client_binary_protocol_thread_unregister (gpointer thread
)
628 static void G_GNUC_UNUSED
629 sgen_client_binary_protocol_missing_remset (gpointer obj
, gpointer obj_vtable
, int offset
, gpointer value
, gpointer value_vtable
, gboolean value_pinned
)
633 static void G_GNUC_UNUSED
634 sgen_client_binary_protocol_cement_reset (void)
638 static void G_GNUC_UNUSED
639 sgen_client_binary_protocol_domain_unload_begin (gpointer domain
)
643 static void G_GNUC_UNUSED
644 sgen_client_binary_protocol_domain_unload_end (gpointer domain
)
648 static void G_GNUC_UNUSED
649 sgen_client_binary_protocol_gray_enqueue (gpointer queue
, gpointer cursor
, gpointer value
)
653 static void G_GNUC_UNUSED
654 sgen_client_binary_protocol_gray_dequeue (gpointer queue
, gpointer cursor
, gpointer value
)
658 int sgen_thread_handshake (BOOL suspend
);
659 gboolean
sgen_suspend_thread (SgenThreadInfo
*info
);
660 gboolean
sgen_resume_thread (SgenThreadInfo
*info
);
661 void sgen_wait_for_suspend_ack (int count
);
663 #ifdef HAVE_KW_THREAD
664 extern __thread SgenThreadInfo
*sgen_thread_info
;
665 #define TLAB_ACCESS_INIT
666 #define IN_CRITICAL_REGION sgen_thread_info->client_info.in_critical_region
668 extern MonoNativeTlsKey thread_info_key
;
669 #define TLAB_ACCESS_INIT SgenThreadInfo *__thread_info__ = mono_native_tls_get_value (thread_info_key)
670 #define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
673 #ifndef DISABLE_CRITICAL_REGION
675 #ifdef HAVE_KW_THREAD
676 #define IN_CRITICAL_REGION sgen_thread_info->client_info.in_critical_region
678 #define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
681 /* Enter must be visible before anything is done in the critical region. */
682 #define ENTER_CRITICAL_REGION do { mono_atomic_store_acquire (&IN_CRITICAL_REGION, 1); } while (0)
684 /* Exit must make sure all critical regions stores are visible before it signal the end of the region.
685 * We don't need to emit a full barrier since we
687 #define EXIT_CRITICAL_REGION do { mono_atomic_store_release (&IN_CRITICAL_REGION, 0); } while (0)
691 #define SGEN_TV_DECLARE(name) gint64 name
692 #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
693 #define SGEN_TV_ELAPSED(start,end) ((long)(end-start))
695 typedef MonoSemType SgenSemaphore
;
697 #define SGEN_SEMAPHORE_INIT(sem,initial) MONO_SEM_INIT ((sem), (initial))
698 #define SGEN_SEMAPHORE_POST(sem) MONO_SEM_POST ((sem))
699 #define SGEN_SEMAPHORE_WAIT(sem) MONO_SEM_WAIT ((sem))
701 gboolean
sgen_has_critical_method (void);
702 gboolean
sgen_is_critical_method (MonoMethod
*method
);
704 void sgen_set_use_managed_allocator (gboolean flag
);
705 gboolean
sgen_is_managed_allocator (MonoMethod
*method
);
706 gboolean
sgen_has_managed_allocator (void);
708 void sgen_scan_for_registered_roots_in_domain (MonoDomain
*domain
, int root_type
);