Merge pull request #4570 from lateralusX/jlorenss/visual_studio_msbuild_fix
[mono.git] / mono / metadata / sgen-client-mono.h
1 /**
2  * \file
3  * Mono's client definitions for SGen.
4  *
5  * Copyright (C) 2014 Xamarin Inc
6  *
7  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8  */
9
10 #ifdef SGEN_DEFINE_OBJECT_VTABLE
11
12 #include "sgen/sgen-archdep.h"
13 #include "utils/mono-threads.h"
14 #include "utils/mono-mmap.h"
15 #include "metadata/object-internals.h"
16
17 typedef MonoObject GCObject;
18 typedef MonoVTable* GCVTable;
19
20 static inline GCVTable
21 SGEN_LOAD_VTABLE_UNCHECKED (GCObject *obj)
22 {
23         return obj->vtable;
24 }
25
26 static inline SgenDescriptor
27 sgen_vtable_get_descriptor (GCVTable vtable)
28 {
29         return (SgenDescriptor)vtable->gc_descr;
30 }
31
32 typedef struct _SgenClientThreadInfo SgenClientThreadInfo;
33 struct _SgenClientThreadInfo {
34         MonoThreadInfo info;
35
36         /*
37          * `skip` is set to TRUE when STW fails to suspend a thread, most probably because
38          * the underlying thread is dead.
39         */
40         gboolean skip, suspend_done;
41         volatile int in_critical_region;
42
43         /*
44         This is set the argument of mono_gc_set_skip_thread.
45
46         A thread that knowingly holds no managed state can call this
47         function around blocking loops to reduce the GC burden by not
48         been scanned.
49         */
50         gboolean gc_disabled;
51
52 #ifdef SGEN_POSIX_STW
53         /* This is -1 until the first suspend. */
54         int signal;
55         /* FIXME: kill this, we only use signals on systems that have rt-posix, which doesn't have issues with duplicates. */
56         unsigned int stop_count; /* to catch duplicate signals. */
57 #endif
58
59         gpointer runtime_data;
60
61         void *stack_end;
62         void *stack_start;
63         void *stack_start_limit;
64
65         MonoContext ctx;                /* ditto */
66 };
67
68 #else
69
70 #include "metadata/profiler-private.h"
71 #include "utils/dtrace.h"
72 #include "utils/mono-counters.h"
73 #include "utils/mono-logger-internals.h"
74 #include "utils/mono-time.h"
75 #include "utils/mono-os-semaphore.h"
76 #include "metadata/sgen-bridge-internals.h"
77
78 extern void mono_sgen_register_moved_object (void *obj, void *destination);
79 extern void mono_sgen_gc_event_moves (void);
80
81 extern void mono_sgen_init_stw (void);
82
83 enum {
84         INTERNAL_MEM_EPHEMERON_LINK = INTERNAL_MEM_FIRST_CLIENT,
85         INTERNAL_MEM_MOVED_OBJECT,
86         INTERNAL_MEM_MAX
87 };
88
89 static inline mword
90 sgen_mono_array_size (GCVTable vtable, MonoArray *array, mword *bounds_size, mword descr)
91 {
92         mword size, size_without_bounds;
93         int element_size;
94
95         if ((descr & DESC_TYPE_MASK) == DESC_TYPE_VECTOR)
96                 element_size = ((descr) >> VECTOR_ELSIZE_SHIFT) & MAX_ELEMENT_SIZE;
97         else
98                 element_size = vtable->klass->sizes.element_size;
99
100         size_without_bounds = size = MONO_SIZEOF_MONO_ARRAY + element_size * mono_array_length_fast (array);
101
102         if (G_UNLIKELY (array->bounds)) {
103                 size += sizeof (mono_array_size_t) - 1;
104                 size &= ~(sizeof (mono_array_size_t) - 1);
105                 size += sizeof (MonoArrayBounds) * vtable->klass->rank;
106         }
107
108         if (bounds_size)
109                 *bounds_size = size - size_without_bounds;
110         return size;
111 }
112
113 #define SGEN_CLIENT_OBJECT_HEADER_SIZE          (sizeof (GCObject))
114 #define SGEN_CLIENT_MINIMUM_OBJECT_SIZE         SGEN_CLIENT_OBJECT_HEADER_SIZE
115
116 static mword /*__attribute__ ((__noinline__)) not sure if this hint is a good idea*/
117 sgen_client_slow_object_get_size (GCVTable vtable, GCObject* o)
118 {
119         MonoClass *klass = ((MonoVTable*)vtable)->klass;
120
121         /*
122          * We depend on mono_string_length_fast and
123          * mono_array_length_fast not using the object's vtable.
124          */
125         if (klass == mono_defaults.string_class) {
126                 return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
127         } else if (klass->rank) {
128                 return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, 0);
129         } else {
130                 /* from a created object: the class must be inited already */
131                 return klass->instance_size;
132         }
133 }
134
135 /*
136  * This function can be called on an object whose first word, the
137  * vtable field, is not intact.  This is necessary for the parallel
138  * collector.
139  */
140 static MONO_NEVER_INLINE mword
141 sgen_client_par_object_get_size (GCVTable vtable, GCObject* o)
142 {
143         SgenDescriptor descr = sgen_vtable_get_descriptor (vtable);
144         mword type = descr & DESC_TYPE_MASK;
145
146         if (type == DESC_TYPE_RUN_LENGTH || type == DESC_TYPE_SMALL_PTRFREE) {
147                 mword size = descr & 0xfff8;
148                 SGEN_ASSERT (9, size >= sizeof (MonoObject), "Run length object size to small");
149                 return size;
150         } else if (descr == SGEN_DESC_STRING) {
151                 return G_STRUCT_OFFSET (MonoString, chars) + 2 * mono_string_length_fast ((MonoString*) o) + 2;
152         } else if (type == DESC_TYPE_VECTOR) {
153                 return sgen_mono_array_size (vtable, (MonoArray*)o, NULL, descr);
154         }
155
156         return sgen_client_slow_object_get_size (vtable, o);
157 }
158
159 static MONO_ALWAYS_INLINE size_t G_GNUC_UNUSED
160 sgen_client_array_element_size (GCVTable gc_vtable)
161 {
162         MonoVTable *vt = (MonoVTable*)gc_vtable;
163         return mono_array_element_size (vt->klass);
164 }
165
166 static MONO_ALWAYS_INLINE G_GNUC_UNUSED char*
167 sgen_client_array_data_start (GCObject *obj)
168 {
169         return (char*)(obj) +  G_STRUCT_OFFSET (MonoArray, vector);
170 }
171
172 static MONO_ALWAYS_INLINE size_t G_GNUC_UNUSED
173 sgen_client_array_length (GCObject *obj)
174 {
175         return mono_array_length_fast ((MonoArray*)obj);
176 }
177
178 static MONO_ALWAYS_INLINE gboolean G_GNUC_UNUSED
179 sgen_client_object_is_array_fill (GCObject *o)
180 {
181         return ((MonoObject*)o)->synchronisation == GINT_TO_POINTER (-1);
182 }
183
184 static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
185 sgen_client_pre_copy_checks (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
186 {
187         MonoVTable *vt = (MonoVTable*)gc_vtable;
188         SGEN_ASSERT (9, vt->klass->inited, "vtable %p for class %s:%s was not initialized", vt, vt->klass->name_space, vt->klass->name);
189 }
190
191 static MONO_ALWAYS_INLINE void G_GNUC_UNUSED
192 sgen_client_update_copied_object (char *destination, GCVTable gc_vtable, void *obj, mword objsize)
193 {
194         MonoVTable *vt = (MonoVTable*)gc_vtable;
195         if (G_UNLIKELY (vt->rank && ((MonoArray*)obj)->bounds)) {
196                 MonoArray *array = (MonoArray*)destination;
197                 array->bounds = (MonoArrayBounds*)((char*)destination + ((char*)((MonoArray*)obj)->bounds - (char*)obj));
198                 SGEN_LOG (9, "Array instance %p: size: %lu, rank: %d, length: %lu", array, (unsigned long)objsize, vt->rank, (unsigned long)mono_array_length (array));
199         }
200
201         if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_GC_MOVES))
202                 mono_sgen_register_moved_object (obj, destination);
203 }
204
205 #ifdef XDOMAIN_CHECKS_IN_WBARRIER
206 extern gboolean sgen_mono_xdomain_checks;
207
208 #define sgen_client_wbarrier_generic_nostore_check(ptr) do {            \
209                 /* FIXME: ptr_in_heap must be called with the GC lock held */ \
210                 if (sgen_mono_xdomain_checks && *(MonoObject**)ptr && ptr_in_heap (ptr)) { \
211                         char *start = find_object_for_ptr (ptr);        \
212                         MonoObject *value = *(MonoObject**)ptr;         \
213                         LOCK_GC;                                        \
214                         SGEN_ASSERT (0, start, "Write barrier outside an object?"); \
215                         if (start) {                                    \
216                                 MonoObject *obj = (MonoObject*)start;   \
217                                 if (obj->vtable->domain != value->vtable->domain) \
218                                         SGEN_ASSERT (0, is_xdomain_ref_allowed (ptr, start, obj->vtable->domain), "Cross-domain ref not allowed"); \
219                         }                                               \
220                         UNLOCK_GC;                                      \
221                 }                                                       \
222         } while (0)
223 #else
224 #define sgen_client_wbarrier_generic_nostore_check(ptr)
225 #endif
226
227 static gboolean G_GNUC_UNUSED
228 sgen_client_object_has_critical_finalizer (GCObject *obj)
229 {
230         MonoClass *klass;
231
232         if (!mono_defaults.critical_finalizer_object)
233                 return FALSE;
234
235         klass = SGEN_LOAD_VTABLE (obj)->klass;
236
237         return mono_class_has_parent_fast (klass, mono_defaults.critical_finalizer_object);
238 }
239
240 const char* sgen_client_vtable_get_namespace (GCVTable vtable);
241 const char* sgen_client_vtable_get_name (GCVTable vtable);
242
243 static gboolean G_GNUC_UNUSED
244 sgen_client_bridge_need_processing (void)
245 {
246         return sgen_need_bridge_processing ();
247 }
248
249 static void G_GNUC_UNUSED
250 sgen_client_bridge_reset_data (void)
251 {
252         sgen_bridge_reset_data ();
253 }
254
255 static void G_GNUC_UNUSED
256 sgen_client_bridge_processing_stw_step (void)
257 {
258         sgen_bridge_processing_stw_step ();
259 }
260
261 static void G_GNUC_UNUSED
262 sgen_client_bridge_wait_for_processing (void)
263 {
264         mono_gc_wait_for_bridge_processing ();
265 }
266
267 static void G_GNUC_UNUSED
268 sgen_client_bridge_processing_finish (int generation)
269 {
270         sgen_bridge_processing_finish (generation);
271 }
272
273 static gboolean G_GNUC_UNUSED
274 sgen_client_bridge_is_bridge_object (GCObject *obj)
275 {
276         return sgen_is_bridge_object (obj);
277 }
278
279 static void G_GNUC_UNUSED
280 sgen_client_bridge_register_finalized_object (GCObject *object)
281 {
282         sgen_bridge_register_finalized_object (object);
283 }
284
285 static void G_GNUC_UNUSED
286 sgen_client_binary_protocol_collection_requested (int generation, size_t requested_size, gboolean force)
287 {
288         MONO_GC_REQUESTED (generation, requested_size, force);
289 }
290
291 static void G_GNUC_UNUSED
292 sgen_client_binary_protocol_collection_begin (int minor_gc_count, int generation)
293 {
294         MONO_GC_BEGIN (generation);
295
296         mono_profiler_gc_event (MONO_GC_EVENT_START, generation);
297
298 #ifndef DISABLE_PERFCOUNTERS
299         if (generation == GENERATION_NURSERY)
300                 mono_perfcounters->gc_collections0++;
301         else
302                 mono_perfcounters->gc_collections1++;
303 #endif
304 }
305
306 static void G_GNUC_UNUSED
307 sgen_client_binary_protocol_collection_end (int minor_gc_count, int generation, long long num_objects_scanned, long long num_unique_objects_scanned)
308 {
309         MONO_GC_END (generation);
310
311         mono_profiler_gc_event (MONO_GC_EVENT_END, generation);
312 }
313
314 static void G_GNUC_UNUSED
315 sgen_client_binary_protocol_concurrent_start (void)
316 {
317         MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD);
318 }
319
320 static void G_GNUC_UNUSED
321 sgen_client_binary_protocol_concurrent_update (void)
322 {
323         MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
324 }
325
326 static void G_GNUC_UNUSED
327 sgen_client_binary_protocol_concurrent_finish (void)
328 {
329         MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, sgen_get_major_collector ()->get_and_reset_num_major_objects_marked ());
330 }
331
332 static void G_GNUC_UNUSED
333 sgen_client_binary_protocol_sweep_begin (int generation, int full_sweep)
334 {
335         MONO_GC_SWEEP_BEGIN (generation, full_sweep);
336 }
337
338 static void G_GNUC_UNUSED
339 sgen_client_binary_protocol_sweep_end (int generation, int full_sweep)
340 {
341         MONO_GC_SWEEP_END (generation, full_sweep);
342 }
343
344 static void G_GNUC_UNUSED
345 sgen_client_binary_protocol_world_stopping (int generation, long long timestamp, gpointer thread)
346 {
347         MONO_GC_WORLD_STOP_BEGIN ();
348
349         mono_profiler_gc_event (MONO_GC_EVENT_PRE_STOP_WORLD, generation);
350 }
351
352 static void G_GNUC_UNUSED
353 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)
354 {
355         MONO_GC_WORLD_STOP_END ();
356
357         mono_profiler_gc_event (MONO_GC_EVENT_POST_STOP_WORLD, generation);
358 }
359
360 static void G_GNUC_UNUSED
361 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)
362 {
363         MONO_GC_WORLD_RESTART_BEGIN (generation);
364
365         mono_profiler_gc_event (MONO_GC_EVENT_PRE_START_WORLD, generation);
366 }
367
368 static void G_GNUC_UNUSED
369 sgen_client_binary_protocol_world_restarted (int generation, long long timestamp)
370 {
371         MONO_GC_WORLD_RESTART_END (generation);
372
373         mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD, generation);
374 }
375
376 static void G_GNUC_UNUSED
377 sgen_client_binary_protocol_block_alloc (gpointer addr, size_t size)
378 {
379 }
380
381 static void G_GNUC_UNUSED
382 sgen_client_binary_protocol_block_free (gpointer addr, size_t size)
383 {
384 }
385
386 static void G_GNUC_UNUSED
387 sgen_client_binary_protocol_block_set_state (gpointer addr, size_t size, int old, int new_)
388 {
389 }
390
391 static void G_GNUC_UNUSED
392 sgen_client_binary_protocol_mark_start (int generation)
393 {
394         mono_profiler_gc_event (MONO_GC_EVENT_MARK_START, generation);
395 }
396
397 static void G_GNUC_UNUSED
398 sgen_client_binary_protocol_mark_end (int generation)
399 {
400         mono_profiler_gc_event (MONO_GC_EVENT_MARK_END, generation);
401 }
402
403 static void G_GNUC_UNUSED
404 sgen_client_binary_protocol_reclaim_start (int generation)
405 {
406         mono_profiler_gc_event (MONO_GC_EVENT_RECLAIM_START, generation);
407 }
408
409 static void G_GNUC_UNUSED
410 sgen_client_binary_protocol_reclaim_end (int generation)
411 {
412         mono_profiler_gc_event (MONO_GC_EVENT_RECLAIM_END, generation);
413 }
414
415 static void
416 mono_binary_protocol_alloc_generic (gpointer obj, gpointer vtable, size_t size, gboolean pinned)
417 {
418 #ifdef ENABLE_DTRACE
419         const char *namespace = sgen_client_vtable_get_namespace (vtable);
420         const char *name = sgen_client_vtable_get_name (vtable);
421
422         if (sgen_ptr_in_nursery (obj)) {
423                 if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ()))
424                         MONO_GC_NURSERY_OBJ_ALLOC ((mword)obj, size, namespace, name);
425         } else {
426                 if (size > SGEN_MAX_SMALL_OBJ_SIZE) {
427                         if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()))
428                                 MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword)obj, size, namespace, name);
429                 } else if (pinned) {
430                         MONO_GC_MAJOR_OBJ_ALLOC_PINNED ((mword)obj, size, namespace, name);
431                 }
432         }
433 #endif
434 }
435
436 static void G_GNUC_UNUSED
437 sgen_client_binary_protocol_alloc (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
438 {
439         mono_binary_protocol_alloc_generic (obj, vtable, size, FALSE);
440 }
441
442 static void G_GNUC_UNUSED
443 sgen_client_binary_protocol_alloc_pinned (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
444 {
445         mono_binary_protocol_alloc_generic (obj, vtable, size, TRUE);
446 }
447
448 static void G_GNUC_UNUSED
449 sgen_client_binary_protocol_alloc_degraded (gpointer obj, gpointer vtable, size_t size, gpointer provenance)
450 {
451         MONO_GC_MAJOR_OBJ_ALLOC_DEGRADED ((mword)obj, size, sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
452 }
453
454 static void G_GNUC_UNUSED
455 sgen_client_binary_protocol_card_scan (gpointer start, size_t size)
456 {
457 }
458
459 static void G_GNUC_UNUSED
460 sgen_client_binary_protocol_pin_stage (gpointer addr_ptr, gpointer addr)
461 {
462 }
463
464 static void G_GNUC_UNUSED
465 sgen_client_binary_protocol_cement_stage (gpointer addr)
466 {
467 }
468
469 static void G_GNUC_UNUSED
470 sgen_client_binary_protocol_pin (gpointer obj, gpointer vtable, size_t size)
471 {
472 #ifdef ENABLE_DTRACE
473         if (G_UNLIKELY (MONO_GC_OBJ_PINNED_ENABLED ())) {
474                 int gen = sgen_ptr_in_nursery (obj) ? GENERATION_NURSERY : GENERATION_OLD;
475                 MONO_GC_OBJ_PINNED ((mword)obj,
476                                 sgen_safe_object_get_size (obj),
477                                 sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable), gen);
478         }
479 #endif
480 }
481
482 static void G_GNUC_UNUSED
483 sgen_client_binary_protocol_mark (gpointer obj, gpointer vtable, size_t size)
484 {
485 }
486
487 static void G_GNUC_UNUSED
488 sgen_client_binary_protocol_scan_begin (gpointer obj, gpointer vtable, size_t size)
489 {
490 }
491
492 static void G_GNUC_UNUSED
493 sgen_client_binary_protocol_scan_vtype_begin (gpointer obj, size_t size)
494 {
495 }
496
497 static void G_GNUC_UNUSED
498 sgen_client_binary_protocol_scan_process_reference (gpointer obj, gpointer ptr, gpointer value)
499 {
500 }
501
502 static void G_GNUC_UNUSED
503 sgen_client_binary_protocol_scan_stack (gpointer thread, gpointer stack_start, gpointer stack_end, int skip_reason)
504 {
505 }
506
507 static void G_GNUC_UNUSED
508 sgen_client_binary_protocol_wbarrier (gpointer ptr, gpointer value, gpointer value_vtable)
509 {
510 }
511
512 static void G_GNUC_UNUSED
513 sgen_client_binary_protocol_cement (gpointer ptr, gpointer vtable, size_t size)
514 {
515 #ifdef ENABLE_DTRACE
516         if (G_UNLIKELY (MONO_GC_OBJ_CEMENTED_ENABLED())) {
517                 MONO_GC_OBJ_CEMENTED ((mword)ptr, sgen_safe_object_get_size ((GCObject*)ptr),
518                                 sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
519         }
520 #endif
521 }
522
523 static void G_GNUC_UNUSED
524 sgen_client_binary_protocol_copy (gpointer from, gpointer to, gpointer vtable, size_t size)
525 {
526 #ifdef ENABLE_DTRACE
527         if (G_UNLIKELY (MONO_GC_OBJ_MOVED_ENABLED ())) {
528                 int dest_gen = sgen_ptr_in_nursery (to) ? GENERATION_NURSERY : GENERATION_OLD;
529                 int src_gen = sgen_ptr_in_nursery (from) ? GENERATION_NURSERY : GENERATION_OLD;
530                 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));
531         }
532 #endif
533 }
534
535 static void G_GNUC_UNUSED
536 sgen_client_binary_protocol_global_remset (gpointer ptr, gpointer value, gpointer value_vtable)
537 {
538 #ifdef ENABLE_DTRACE
539         if (G_UNLIKELY (MONO_GC_GLOBAL_REMSET_ADD_ENABLED ())) {
540                 MONO_GC_GLOBAL_REMSET_ADD ((mword)ptr, (mword)value, sgen_safe_object_get_size (value),
541                                 sgen_client_vtable_get_namespace (value_vtable), sgen_client_vtable_get_name (value_vtable));
542         }
543 #endif
544 }
545
546 static void G_GNUC_UNUSED
547 sgen_client_binary_protocol_mod_union_remset (gpointer obj, gpointer ptr, gpointer value, gpointer value_vtable)
548 {
549 }
550
551 static void G_GNUC_UNUSED
552 sgen_client_binary_protocol_ptr_update (gpointer ptr, gpointer old_value, gpointer new_value, gpointer vtable, size_t size)
553 {
554 }
555
556 static void G_GNUC_UNUSED
557 sgen_client_binary_protocol_cleanup (gpointer ptr, gpointer vtable, size_t size)
558 {
559 }
560
561 static void G_GNUC_UNUSED
562 sgen_client_binary_protocol_dislink_add (gpointer link, gpointer obj, gboolean track)
563 {
564 }
565
566 static void G_GNUC_UNUSED
567 sgen_client_binary_protocol_dislink_update (gpointer link, gpointer obj, gboolean track)
568 {
569 #ifdef ENABLE_DTRACE
570         if (MONO_GC_WEAK_UPDATE_ENABLED ()) {
571                 GCVTable vt = obj ? SGEN_LOAD_VTABLE (obj) : NULL;
572                 MONO_GC_WEAK_UPDATE ((mword)link,
573                                 (mword)obj,
574                                 obj ? (mword)sgen_safe_object_get_size (obj) : (mword)0,
575                                 obj ? sgen_client_vtable_get_namespace (vt) : NULL,
576                                 obj ? sgen_client_vtable_get_name (vt) : NULL,
577                                 track ? 1 : 0);
578         }
579 #endif
580 }
581
582 static void G_GNUC_UNUSED
583 sgen_client_binary_protocol_dislink_remove (gpointer link, gboolean track)
584 {
585 }
586
587 static void G_GNUC_UNUSED
588 sgen_client_binary_protocol_empty (gpointer start, size_t size)
589 {
590         if (sgen_ptr_in_nursery (start))
591                 MONO_GC_NURSERY_SWEPT ((mword)start, size);
592         else
593                 MONO_GC_MAJOR_SWEPT ((mword)start, size);
594 }
595
596 static void G_GNUC_UNUSED
597 sgen_client_binary_protocol_thread_suspend (gpointer thread, gpointer stopped_ip)
598 {
599 }
600
601 static void G_GNUC_UNUSED
602 sgen_client_binary_protocol_thread_restart (gpointer thread)
603 {
604 }
605
606 static void G_GNUC_UNUSED
607 sgen_client_binary_protocol_thread_register (gpointer thread)
608 {
609 }
610
611 static void G_GNUC_UNUSED
612 sgen_client_binary_protocol_thread_unregister (gpointer thread)
613 {
614 }
615
616 static void G_GNUC_UNUSED
617 sgen_client_binary_protocol_missing_remset (gpointer obj, gpointer obj_vtable, int offset, gpointer value, gpointer value_vtable, gboolean value_pinned)
618 {
619 }
620
621 static void G_GNUC_UNUSED
622 sgen_client_binary_protocol_cement_reset (void)
623 {
624 }
625
626 static void G_GNUC_UNUSED
627 sgen_client_binary_protocol_domain_unload_begin (gpointer domain)
628 {
629 }
630
631 static void G_GNUC_UNUSED
632 sgen_client_binary_protocol_domain_unload_end (gpointer domain)
633 {
634 }
635
636 static void G_GNUC_UNUSED
637 sgen_client_binary_protocol_gray_enqueue (gpointer queue, gpointer cursor, gpointer value)
638 {
639 }
640
641 static void G_GNUC_UNUSED
642 sgen_client_binary_protocol_gray_dequeue (gpointer queue, gpointer cursor, gpointer value)
643 {
644 }
645
646 static void G_GNUC_UNUSED
647 sgen_client_binary_protocol_major_card_table_scan_start (long long timestamp, gboolean mod_union)
648 {
649 }
650
651 static void G_GNUC_UNUSED
652 sgen_client_binary_protocol_major_card_table_scan_end (long long timestamp, gboolean mod_union)
653 {
654 }
655
656 static void G_GNUC_UNUSED
657 sgen_client_binary_protocol_los_card_table_scan_start (long long timestamp, gboolean mod_union)
658 {
659 }
660
661 static void G_GNUC_UNUSED
662 sgen_client_binary_protocol_los_card_table_scan_end (long long timestamp, gboolean mod_union)
663 {
664 }
665
666 static void G_GNUC_UNUSED
667 sgen_client_binary_protocol_finish_gray_stack_start (long long timestamp, int generation)
668 {
669 }
670
671 static void G_GNUC_UNUSED
672 sgen_client_binary_protocol_finish_gray_stack_end (long long timestamp, int generation)
673 {
674 }
675
676 static void G_GNUC_UNUSED
677 sgen_client_binary_protocol_worker_finish (long long timestamp, gboolean forced)
678 {
679 }
680
681 static void G_GNUC_UNUSED
682 sgen_client_binary_protocol_evacuating_blocks (size_t block_size)
683 {
684 }
685
686 static void G_GNUC_UNUSED
687 sgen_client_binary_protocol_concurrent_sweep_end (long long timestamp)
688 {
689 }
690
691 static void G_GNUC_UNUSED
692 sgen_client_binary_protocol_header (long long check, int version, int ptr_size, gboolean little_endian)
693 {
694 }
695
696 static void G_GNUC_UNUSED
697 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)
698 {
699 }
700
701 #define TLAB_ACCESS_INIT        SgenThreadInfo *__thread_info__ = (SgenThreadInfo*)mono_tls_get_sgen_thread_info ()
702 #define IN_CRITICAL_REGION (__thread_info__->client_info.in_critical_region)
703
704 /* Enter must be visible before anything is done in the critical region. */
705 #define ENTER_CRITICAL_REGION do { mono_atomic_store_acquire (&IN_CRITICAL_REGION, 1); } while (0)
706
707 /* Exit must make sure all critical regions stores are visible before it signal the end of the region. 
708  * We don't need to emit a full barrier since we
709  */
710 #define EXIT_CRITICAL_REGION  do { mono_atomic_store_release (&IN_CRITICAL_REGION, 0); } while (0)
711
712 #ifndef DISABLE_CRITICAL_REGION
713 /*
714  * We can only use a critical region in the managed allocator if the JIT supports OP_ATOMIC_STORE_I4.
715  *
716  * TODO: Query the JIT instead of this ifdef hack.
717  */
718 #if defined (TARGET_X86) || defined (TARGET_AMD64) || (defined (TARGET_ARM) && defined (HAVE_ARMV7)) || defined (TARGET_ARM64)
719 #define MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
720 #endif
721 #endif
722
723 #define SGEN_TV_DECLARE(name) gint64 name
724 #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
725 #define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
726
727 guint64 mono_time_since_last_stw (void);
728
729 typedef MonoSemType SgenSemaphore;
730
731 #define SGEN_SEMAPHORE_INIT(sem,initial)        mono_os_sem_init ((sem), (initial))
732 #define SGEN_SEMAPHORE_POST(sem)                mono_os_sem_post ((sem))
733 #define SGEN_SEMAPHORE_WAIT(sem)                mono_os_sem_wait ((sem), MONO_SEM_FLAGS_NONE)
734
735 gboolean sgen_has_critical_method (void);
736 gboolean sgen_is_critical_method (MonoMethod *method);
737
738 void sgen_set_use_managed_allocator (gboolean flag);
739 gboolean sgen_is_managed_allocator (MonoMethod *method);
740 gboolean sgen_has_managed_allocator (void);
741
742 void sgen_scan_for_registered_roots_in_domain (MonoDomain *domain, int root_type);
743 void sgen_null_links_for_domain (MonoDomain *domain);
744
745 #endif