New test.
[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 gint64
45 mono_gc_get_used_size (void)
46 {
47         return GC_get_heap_size () - GC_get_free_bytes ();
48 }
49
50 gint64
51 mono_gc_get_heap_size (void)
52 {
53         return GC_get_heap_size ();
54 }
55
56 void
57 mono_gc_disable (void)
58 {
59 #ifdef HAVE_GC_ENABLE
60         GC_disable ();
61 #else
62         g_assert_not_reached ();
63 #endif
64 }
65
66 void
67 mono_gc_enable (void)
68 {
69 #ifdef HAVE_GC_ENABLE
70         GC_enable ();
71 #else
72         g_assert_not_reached ();
73 #endif
74 }
75
76 gboolean
77 mono_gc_is_gc_thread (void)
78 {
79 #ifdef USE_INCLUDED_LIBGC
80         return GC_thread_is_registered ();
81 #else
82         return TRUE;
83 #endif
84 }
85
86 gboolean
87 mono_gc_register_thread (void *baseptr)
88 {
89         if (mono_gc_is_gc_thread())
90                 return TRUE;
91 #if defined(USE_INCLUDED_LIBGC) && !defined(PLATFORM_WIN32)
92         return GC_thread_register_foreign (baseptr);
93 #else
94         return FALSE;
95 #endif
96 }
97
98 extern int GC_is_marked (void *p);
99
100 gboolean
101 mono_object_is_alive (MonoObject* o)
102 {
103 #ifdef USE_INCLUDED_LIBGC
104         return GC_is_marked (o);
105 #else
106         return TRUE;
107 #endif
108 }
109
110 #ifdef USE_INCLUDED_LIBGC
111
112 static void
113 on_gc_notification (GCEventType event)
114 {
115         mono_profiler_gc_event ((MonoGCEvent) event, 0);
116 }
117  
118 static void
119 on_gc_heap_resize (size_t new_size)
120 {
121         mono_profiler_gc_heap_resize (new_size);
122 }
123
124 void
125 mono_gc_enable_events (void)
126 {
127         GC_notify_event = on_gc_notification;
128         GC_on_heap_resize = on_gc_heap_resize;
129 }
130
131 #else
132
133 void
134 mono_gc_enable_events (void)
135 {
136 }
137
138 #endif
139
140 void
141 mono_gc_weak_link_add (void **link_addr, MonoObject *obj)
142 {
143         /* libgc requires that we use HIDE_POINTER... */
144         *link_addr = (void*)HIDE_POINTER (obj);
145         GC_GENERAL_REGISTER_DISAPPEARING_LINK (link_addr, obj);
146 }
147
148 void
149 mono_gc_weak_link_remove (void **link_addr)
150 {
151         GC_unregister_disappearing_link (link_addr);
152         *link_addr = NULL;
153 }
154
155 MonoObject*
156 mono_gc_weak_link_get (void **link_addr)
157 {
158         MonoObject *obj = REVEAL_POINTER (*link_addr);
159         if (obj == (MonoObject *) -1)
160                 return NULL;
161         return obj;
162 }
163
164 void*
165 mono_gc_make_descr_from_bitmap (gsize *bitmap, int numbits)
166 {
167         return NULL;
168 }
169
170 void*
171 mono_gc_alloc_fixed (size_t size, void *descr)
172 {
173         return GC_MALLOC (size);
174 }
175
176 void
177 mono_gc_free_fixed (void* addr)
178 {
179 }
180
181 int
182 mono_gc_invoke_finalizers (void)
183 {
184         /* There is a bug in GC_invoke_finalizer () in versions <= 6.2alpha4:
185          * the 'mem_freed' variable is not initialized when there are no
186          * objects to finalize, which leads to strange behavior later on.
187          * The check is necessary to work around that bug.
188          */
189         if (GC_should_invoke_finalizers ())
190                 return GC_invoke_finalizers ();
191         return 0;
192 }
193
194 gboolean
195 mono_gc_pending_finalizers (void)
196 {
197         return GC_should_invoke_finalizers ();
198 }
199
200 void
201 mono_gc_wbarrier_set_field (MonoObject *obj, gpointer field_ptr, MonoObject* value)
202 {
203         *(void**)field_ptr = value;
204 }
205
206 void
207 mono_gc_wbarrier_set_arrayref (MonoArray *arr, gpointer slot_ptr, MonoObject* value)
208 {
209         *(void**)slot_ptr = value;
210 }
211
212 void
213 mono_gc_wbarrier_arrayref_copy (MonoArray *arr, gpointer slot_ptr, int count)
214 {
215         /* no need to do anything */
216 }
217
218 void
219 mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
220 {
221         *(void**)ptr = value;
222 }
223
224 void
225 mono_gc_wbarrier_value_copy (gpointer dest, gpointer src, int count, MonoClass *klass)
226 {
227 }
228
229 #endif /* no Boehm GC */
230