1 /**
2  * \file
3  * Mono-agnostic GC interface.
4  *
5  * Copyright (C) 2015 Xamarin Inc
6  *
7  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
8  */
9 
10 #ifndef __MONO_METADATA_GCINTERNALAGNOSTIC_H__
11 #define __MONO_METADATA_GCINTERNALAGNOSTIC_H__
12 
13 #include <config.h>
14 #include <glib.h>
15 #include <stdio.h>
16 
17 #include "mono/utils/ward.h"
18 #include "mono/utils/mono-compiler.h"
19 #include "mono/utils/parse.h"
20 #include "mono/utils/memfuncs.h"
21 #ifdef HAVE_SGEN_GC
22 #include "mono/sgen/sgen-conf.h"
23 #endif
24 
25 /* h indicates whether to hide or just tag.
26  * (-!!h ^ p) is used instead of (h ? ~p : p) to avoid multiple mentions of p.
27  */
28 #define MONO_GC_HIDE_POINTER(p,t,h) ((gpointer)(((-(size_t)!!(h) ^ (size_t)(p)) & ~(size_t)3) | ((t) & (size_t)3)))
29 #define MONO_GC_REVEAL_POINTER(p,h) ((gpointer)((-(size_t)!!(h) ^ (size_t)(p)) & ~(size_t)3))
30 
31 #define MONO_GC_POINTER_TAG(p) ((size_t)(p) & (size_t)3)
32 
33 #define MONO_GC_HANDLE_OCCUPIED_MASK (1)
34 #define MONO_GC_HANDLE_VALID_MASK (2)
35 #define MONO_GC_HANDLE_TAG_MASK (MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK)
36 
37 #define MONO_GC_HANDLE_METADATA_POINTER(p,h) (MONO_GC_HIDE_POINTER ((p), MONO_GC_HANDLE_OCCUPIED_MASK, (h)))
38 #define MONO_GC_HANDLE_OBJECT_POINTER(p,h) (MONO_GC_HIDE_POINTER ((p), MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK, (h)))
39 
40 #define MONO_GC_HANDLE_OCCUPIED(slot) ((size_t)(slot) & MONO_GC_HANDLE_OCCUPIED_MASK)
41 #define MONO_GC_HANDLE_VALID(slot) ((size_t)(slot) & MONO_GC_HANDLE_VALID_MASK)
42 
43 #define MONO_GC_HANDLE_TAG(slot) ((size_t)(slot) & MONO_GC_HANDLE_TAG_MASK)
44 
45 #define MONO_GC_HANDLE_IS_OBJECT_POINTER(slot) (MONO_GC_HANDLE_TAG (slot) == (MONO_GC_HANDLE_OCCUPIED_MASK | MONO_GC_HANDLE_VALID_MASK))
46 #define MONO_GC_HANDLE_IS_METADATA_POINTER(slot) (MONO_GC_HANDLE_TAG (slot) == MONO_GC_HANDLE_OCCUPIED_MASK)
47 
48 /* These should match System.Runtime.InteropServices.GCHandleType */
49 typedef enum {
50 	HANDLE_TYPE_MIN = 0,
51 	HANDLE_WEAK = HANDLE_TYPE_MIN,
52 	HANDLE_WEAK_TRACK,
53 	HANDLE_NORMAL,
54 	HANDLE_PINNED,
55 	HANDLE_WEAK_FIELDS,
56 	HANDLE_TYPE_MAX
57 } GCHandleType;
58 
59 #define GC_HANDLE_TYPE_IS_WEAK(x) ((x) <= HANDLE_WEAK_TRACK)
60 
61 #define MONO_GC_HANDLE_TYPE_SHIFT (3)
62 #define MONO_GC_HANDLE_TYPE_MASK ((1 << MONO_GC_HANDLE_TYPE_SHIFT) - 1)
63 #define MONO_GC_HANDLE_TYPE(x) ((GCHandleType)(((x) & MONO_GC_HANDLE_TYPE_MASK) - 1))
64 #define MONO_GC_HANDLE_SLOT(x) ((x) >> MONO_GC_HANDLE_TYPE_SHIFT)
65 #define MONO_GC_HANDLE_TYPE_IS_WEAK(x) ((x) <= HANDLE_WEAK_TRACK)
66 #define MONO_GC_HANDLE(slot, type) (((slot) << MONO_GC_HANDLE_TYPE_SHIFT) | (((type) & MONO_GC_HANDLE_TYPE_MASK) + 1))
67 
68 typedef struct {
69 	gint32 minor_gc_count;
70 	gint32 major_gc_count;
71 	gint64 minor_gc_time;
72 	gint64 major_gc_time;
73 	gint64 major_gc_time_concurrent;
74 } GCStats;
75 
76 extern GCStats gc_stats;
77 
78 #ifdef HAVE_SGEN_GC
79 typedef SgenDescriptor MonoGCDescriptor;
80 #define MONO_GC_DESCRIPTOR_NULL	SGEN_DESCRIPTOR_NULL
81 #else
82 typedef void* MonoGCDescriptor;
83 #define MONO_GC_DESCRIPTOR_NULL NULL
84 #endif
85 
86 gboolean mono_gc_parse_environment_string_extract_number (const char *str, size_t *out);
87 
88 MonoGCDescriptor mono_gc_make_descr_for_object (gsize *bitmap, int numbits, size_t obj_size)
89     MONO_PERMIT (need (sgen_lock_gc));
90 MonoGCDescriptor mono_gc_make_descr_for_array (int vector, gsize *elem_bitmap, int numbits, size_t elem_size)
91     MONO_PERMIT (need (sgen_lock_gc));
92 
93 /* simple interface for data structures needed in the runtime */
94 MonoGCDescriptor mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
95     MONO_PERMIT (need (sgen_lock_gc));
96 
97 /* Return a root descriptor for a vector with repeating refs bitmap */
98 MonoGCDescriptor mono_gc_make_vector_descr (void);
99 
100 /* Return a root descriptor for a root with all refs */
101 MonoGCDescriptor mono_gc_make_root_descr_all_refs (int numbits)
102     MONO_PERMIT (need (sgen_lock_gc));
103 
104 /* Return the bitmap encoded by a descriptor */
105 gsize* mono_gc_get_bitmap_for_descr (MonoGCDescriptor descr, int *numbits);
106 
107 /*
108 These functions must be used when it's possible that either destination is not
109 word aligned or size is not a multiple of word size.
110 */
111 void mono_gc_bzero_atomic (void *dest, size_t size);
112 void mono_gc_bzero_aligned (void *dest, size_t size);
113 void mono_gc_memmove_atomic (void *dest, const void *src, size_t size);
114 void mono_gc_memmove_aligned (void *dest, const void *src, size_t size);
115 
116 FILE *mono_gc_get_logfile (void);
117 
118 /* equivalent to options set via MONO_GC_PARAMS */
119 void mono_gc_params_set (const char* options);
120 /* equivalent to options set via MONO_GC_DEBUG */
121 void mono_gc_debug_set (const char* options);
122 
123 #endif
124