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