* reflection.c (inflate_mono_method): Reuse method instantiation
[mono.git] / mono / metadata / boehm-gc.c
1 /*
2  * boehm-gc.c: GC implementation using either the installed or included Boehm GC.
3  *
4  */
5
6 #include "config.h"
7 #define GC_I_HIDE_POINTERS
8 #include <mono/os/gc_wrapper.h>
9 #include <mono/metadata/mono-gc.h>
10 #include <mono/metadata/gc-internal.h>
11 #include <mono/metadata/profiler-private.h>
12 #include <mono/utils/mono-logger.h>
13
14 #if HAVE_BOEHM_GC
15
16 static void
17 mono_gc_warning (char *msg, GC_word arg)
18 {
19         mono_trace (G_LOG_LEVEL_WARNING, MONO_TRACE_GC, msg, (unsigned long)arg);
20 }
21
22 void
23 mono_gc_base_init (void)
24 {
25         GC_no_dls = TRUE;
26         GC_oom_fn = mono_gc_out_of_memory;
27         GC_set_warn_proc (mono_gc_warning);
28         GC_finalize_on_demand = 1;
29         GC_finalizer_notifier = mono_gc_finalize_notify;
30 }
31
32 void
33 mono_gc_collect (int generation)
34 {
35         GC_gcollect ();
36 }
37
38 int
39 mono_gc_max_generation (void)
40 {
41         return 0;
42 }
43
44 int
45 mono_gc_get_generation  (MonoObject *object)
46 {
47         return 0;
48 }
49
50 int
51 mono_gc_collection_count (int generation)
52 {
53         return GC_gc_no;
54 }
55
56 void
57 mono_gc_add_memory_pressure (gint64 value)
58 {
59 }
60
61 gint64
62 mono_gc_get_used_size (void)
63 {
64         return GC_get_heap_size () - GC_get_free_bytes ();
65 }
66
67 gint64
68 mono_gc_get_heap_size (void)
69 {
70         return GC_get_heap_size ();
71 }
72
73 void
74 mono_gc_disable (void)
75 {
76 #ifdef HAVE_GC_ENABLE
77         GC_disable ();
78 #else
79         g_assert_not_reached ();
80 #endif
81 }
82
83 void
84 mono_gc_enable (void)
85 {
86 #ifdef HAVE_GC_ENABLE
87         GC_enable ();
88 #else
89         g_assert_not_reached ();
90 #endif
91 }
92
93 gboolean
94 mono_gc_is_gc_thread (void)
95 {
96 #ifdef USE_INCLUDED_LIBGC
97         return GC_thread_is_registered ();
98 #else
99         return TRUE;
100 #endif
101 }
102
103 gboolean
104 mono_gc_register_thread (void *baseptr)
105 {
106         if (mono_gc_is_gc_thread())
107                 return TRUE;
108 #if defined(USE_INCLUDED_LIBGC) && !defined(PLATFORM_WIN32)
109         return GC_thread_register_foreign (baseptr);
110 #else
111         return FALSE;
112 #endif
113 }
114
115 extern int GC_is_marked (void *p);
116
117 gboolean
118 mono_object_is_alive (MonoObject* o)
119 {
120 #ifdef USE_INCLUDED_LIBGC
121         return GC_is_marked (o);
122 #else
123         return TRUE;
124 #endif
125 }
126
127 #ifdef USE_INCLUDED_LIBGC
128
129 static void
130 on_gc_notification (GCEventType event)
131 {
132         mono_profiler_gc_event ((MonoGCEvent) event, 0);
133 }
134  
135 static void
136 on_gc_heap_resize (size_t new_size)
137 {
138         mono_profiler_gc_heap_resize (new_size);
139 }
140
141 void
142 mono_gc_enable_events (void)
143 {
144         GC_notify_event = on_gc_notification;
145         GC_on_heap_resize = on_gc_heap_resize;
146 }
147
148 #else
149
150 void
151 mono_gc_enable_events (void)
152 {
153 }
154
155 #endif
156
157 void
158 mono_gc_weak_link_add (void **link_addr, MonoObject *obj)
159 {
160         /* libgc requires that we use HIDE_POINTER... */
161         *link_addr = (void*)HIDE_POINTER (obj);
162         GC_GENERAL_REGISTER_DISAPPEARING_LINK (link_addr, obj);
163 }
164
165 void
166 mono_gc_weak_link_remove (void **link_addr)
167 {
168         GC_unregister_disappearing_link (link_addr);
169         *link_addr = NULL;
170 }
171
172 MonoObject*
173 mono_gc_weak_link_get (void **link_addr)
174 {
175         MonoObject *obj = REVEAL_POINTER (*link_addr);
176         if (obj == (MonoObject *) -1)
177                 return NULL;
178         return obj;
179 }
180
181 void*
182 mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
183 {
184         return NULL;
185 }
186
187 void*
188 mono_gc_alloc_fixed (size_t size, void *descr)
189 {
190         return GC_MALLOC (size);
191 }
192
193 void
194 mono_gc_free_fixed (void* addr)
195 {
196 }
197
198 int
199 mono_gc_invoke_finalizers (void)
200 {
201         /* There is a bug in GC_invoke_finalizer () in versions <= 6.2alpha4:
202          * the 'mem_freed' variable is not initialized when there are no
203          * objects to finalize, which leads to strange behavior later on.
204          * The check is necessary to work around that bug.
205          */
206         if (GC_should_invoke_finalizers ())
207                 return GC_invoke_finalizers ();
208         return 0;
209 }
210
211 gboolean
212 mono_gc_pending_finalizers (void)
213 {
214         return GC_should_invoke_finalizers ();
215 }
216
217 void
218 mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
219 {
220         *(void**)field_ptr = value;
221 }
222
223 void
224 mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
225 {
226         *(void**)slot_ptr = value;
227 }
228
229 void
230 mono_gc_wbarrier_arrayref_copy (MonoArray *arr, gpointer slot_ptr, int count)
231 {
232         /* no need to do anything */
233 }
234
235 void
236 mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
237 {
238         *(void**)ptr = value;
239 }
240
241 void
242 mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
243 {
244 }
245
246 #endif /* no Boehm GC */
247