Rewrote to explain how things are done and why.
[mono.git] / docs / gc-variables-in-c
1                 Handling GC allocated objects in C
2
3 As part of an effort to improve our GC, we need to keep track
4 precisely of where objects are stored, so we can incrementally move
5 from the current conservative GC to a more advanced precise and moving GC.
6 Previously, all global C variables were considered GC roots, but this makes
7 the GC less efficient and increases the chances false references are found
8 to GC memory, hence retaining more memory than needed.
9 We need to tell the GC that some object is supposed to be kept alive
10 as if it was referenced in a global variable.
11
12 For Mono embedders
13 ------------------
14
15 In C#, if you say:
16 class T {
17         static object o;
18 }
19
20 Any object which is stored in `o' is considered to be alive -- it will
21 not be collected. `o' is a member of the root set for the GC.
22
23 However, in C code, this is not the case. If you have:
24
25 static MonoObject* o = NULL;
26
27 The object in `o' will *NOT* be scanned.
28
29 If you need to store an object in a C variable and prevent it from being 
30 collected, you need to acquire a GC handle for it.
31
32         guint32 handle = mono_gchandle_new (my_object, TRUE);
33
34 TRUE means the object will be pinned, so it won't move in memory 
35 when we'll use a moving GC. You can access the MonoObject* referenced by
36 a handle with:
37
38         MonoObject* obj = mono_gchandle_get_target (handle);
39
40 When you don't need the handle anymore you need to call:
41
42         mono_gchandle_free (handle);
43
44 Note that if you assign a new object to the C var, you need to get a new 
45 handle, it's not enough to store a new object in the C var.
46
47 So code that looked like this:
48
49         static MonoObject* o = NULL;
50         ...
51         o = mono_object_new (...);
52         /* use o */
53         ...
54         /* when done to allow the GC to collect o */
55         o = NULL;
56
57 should now be changed to:
58
59         static guint32 o_handle;
60         ...
61         MonoObject *o = mono_object_new (...);
62         o_handle = mono_gchandle_new (o, TRUE);
63         /* use o or mono_gchandle_get_target (o_handle) */
64         ...
65         /* when done to allow the GC to collect o */
66         mono_gchandle_free (o_handle);
67
68
69 For Mono runtime developers
70 ---------------------------
71
72 There are two kinds of static vars used to store pointers to GC memory 
73 that we need to consider:
74 *) objects
75 *) other memory chunks allocated with GC_MALLOC().
76
77 Objects should be dealt with the GC handle support as detailed above.
78 Other items should register the static pointer as an area to be considered
79 part of the root set with the following:
80
81         static gpointer my_gc_data = NULL;
82         ...
83         MONO_GC_REGISTER_ROOT (my_gc_data);
84         my_gc_data = GC_MALLOC (...);
85         
86 Note that this registration is not necessary for *LOCAL* variables,
87 as they are stored on the stack. It is only necessary for global variables,
88 as they are not a part of the GC's root set.
89
90 Once you have done the MONO_GC_REGISTER_ROOT, the variable is just like
91 a static variable in C#. To keep an object alive, you have the variable reference
92 the GC memory, to remove the reference, set the variable to NULL.
93
94 As we prepare the code for a precise GC, GC_MALLOC () will not be used anymore
95 in this way in most cases: we'll have a mechanism to specify exactly where
96 references to GC memory is stored.
97
98 [The rest of this file is useless, just kept until the switchover 
99 of the internals is complete.]
100 Mono Internal Audit
101 -------------------
102
103 Until now, we have been able to store gc references in
104 variables. This means we must audit the source code for where
105 this happens, and ensure the GC knows the right roots.
106
107 Because this is a change from previous behavior, an audit
108 must be done to check for any incorrect uses. Basically,
109 we need to check all variables that contain GC allocated objects. This
110 includes MonoObject*'s, any other pointer to a managed type,
111 and MonoGHashTable's. Any such variable must either
112         1) be added as a root -or-
113         2) only hold values that are referenced elsewhere
114
115 The status of the audit is below:
116
117 metadata
118 --------
119 appdomain.c
120         No variables which can contain GC allocated data
121
122 assembly.c
123         No variables which can contain GC allocated data
124         
125 class.c
126         No variables which can contain GC allocated data
127
128 debug-helpers.c
129         No variables which can contain GC allocated data
130
131 debug-mono-symfile.c
132         No variables
133         
134 decimal.c
135         No variables which can contain GC allocated data
136
137 domain.c
138         static MonoGHashTable * appdomains_list = NULL;
139                 This has been added as a root
140                 
141         static MonoDomain *mono_root_domain = NULL;
142                 this is added to the `appdomains_list' hashtable
143                 which keeps the reference
144         
145         No other variables contain GC allocated data.
146
147 environment.c
148         No variables which can contain GC allocated data
149
150 exception.c
151         No variables.
152
153 file-io.c
154         No variables
155
156 filewatcher.c
157         No variablesNo other variables contain GC allocated data.
158 gc.c
159         static MonoThread *gc_thread;
160                 MonoThread*'s are taken care of by threads.c
161         static gpointer *gc_handles = NULL;
162         static guint8 *gc_handle_types = NULL;
163                 These were added as roots
164                 
165         No other variables contain GC allocated data.
166 icall.c
167         No variables which can contain GC allocated data
168
169 image.c
170         No variables which can contain GC allocated data
171
172 loader.c
173         No variables which can contain GC allocated data
174         
175 locales.c
176         No variables
177         
178 marshal.c
179         static MonoGHashTable *wrapper_hash;
180                 Added as a root
181         static MonoString *string_dummy = NULL;
182                 Added as a root
183         No other variables contain GC allocated data.
184         
185 mempool.c
186         No variables
187         
188 metadata.c
189         No variables which can contain GC allocated data
190
191 monitor.c
192         No variables
193
194 mono-config.c
195         No variables which can contain GC allocated data
196
197 mono-debug.c
198         No variables which can contain GC allocated data
199
200 mono-debug-debugger.c
201         static MonoObject *last_exception = NULL;
202                 Added as a root
203         
204         No other variables contain GC allocated data.
205         
206 mono-endian.c
207         No variables
208
209 monosn.c
210         Not compiled
211
212 object.c
213         static MonoThread *main_thread;
214                 Taken care of by threads.c
215                 
216         No other variables contain GC allocated data.
217 opcodes.c
218         No variables which can contain GC allocated data
219
220 pedump.c
221         No variables which canMONO_GC_REGISTER_ROOT (my_object); contain GC allocated data
222
223 process.c
224         No variables which can contain GC allocated data
225         
226 profiler.c
227         No variables which can contain GC allocated data
228
229 rand.c
230         No variables
231         
232 rawbuffer.c
233         No variables which can contain GC allocated data
234
235 reflection.c
236         No variables which can contain GC allocated data
237         
238 security.c
239         No variables.
240         
241 socket-io.c
242         No variables which can contain GC allocated data
243         
244 string-icalls.c
245         No variables
246         
247 sysmath.c
248         No variables
249         
250 threadpool.c
251         static MonoGHashTable *ares_htable = NULL;
252                 Added as a root
253         
254         No other variables contain GC allocated data.
255 threads.c
256         static MonoGHashTable *threads=NULL
257                 Added as a root. This variable keeps a reference to
258                 all threads, so it covers other files.
259                 
260         No other variables contain GC allocated data.
261 typedef.c
262         No variables
263 unicode.c
264         No variables which can contain GC allocated data
265 verify.c
266         No variables which can contain GC allocated data
267         
268
269 utils/
270 ------
271 monobitset.c
272         No variables which can contain GC allocated data
273 mono-codeman.c
274         No variables which can contain GC allocated data
275 mono-hash.c
276         static MonoGHashNode *node_free_list = NULL;
277                 added as a root
278         No other variables contain GC allocated data.
279 mono-logger.c
280         No variables which can contain GC allocated data
281 mono-math.c
282         No variables which can contain GC allocated data
283 mono-md5.c
284         No variables which can contain GC allocated data
285 mono-sha1.c
286         No variables which can contain GC allocated data
287 mono-uri.c
288         No variables which can contain GC allocated data
289 strenc.c
290         No variables which can contain GC allocated data
291 strtod.c
292         No variables which can contain GC allocated data
293         
294 interp/
295 --------
296 interp.c
297         static MonoGHashTable *method_pointer_hash = NULL;
298                 Added as a root
299         No other variables contain GC allocated data.
300 main.c
301         No variables which can contain GC allocated data
302 mintops.c
303         No variables which can contain GC allocated data
304 transform.c
305         No variables which can contain GC allocated data
306         
307 mini/
308 -----
309
310 abcremoval.c
311         No variables which can contain GC allocated data
312 aot.c
313         static MonoGHashTable *aot_modules;
314                 Added as root
315         No other variables contain GC allocated data.
316 cfold.c
317         No variables which can contain GC allocated data
318 cprop.c
319         Not compiled
320 debug-mini.c
321         No variables.
322 dominators.c
323         No variables
324 driver.c
325         No variables which can contain GC allocated data
326 exceptions-ppc.c
327         No variables which can contain GC allocated data
328 exceptions-s390.c
329         No variables which can contain GC allocated data
330 exceptions-sparc.c
331         No variables which can contain GC allocated data
332 exceptions-x86.c
333         No variables which can contain GC allocated data
334 genmdesc.c
335         Not part of mini
336 graph.c
337         No variables which can contain GC allocated data
338 helpers.c
339         No variables which can contain GC allocated data
340 inssel.c
341         No variables which can contain GC allocated data
342 jit-icalls.c
343         No variables
344 linear-scan.c
345         No variables
346 liveness.c
347         No variables
348 main.c
349         No variables
350 mini.c
351         No variables which can contain GC allocated data
352 mini-exceptions.c
353         No variables which can contain GC allocated data
354 mini-ppc.c
355         No variables which can contain GC allocated data
356 mini-s390.c
357         No variables which can contain G 
358 C allocated data
359 mini-sparc.c
360         No variables which can contain GC allocated data
361 mini-x86.c
362         No variables which can contain GC allocated data
363 regalloc.c
364         No variables which can contain GC allocated data
365 ssa.c
366         No variables which can contain GC allocated data
367 trace.c
368         No variables which can contain GC allocated data
369 tramp-ppc.c
370         No variables which can contain GC allocated data
371 tramp-s390.c
372         No variables which can contain GC allocated data
373 tramp-sparc.c
374         No variables which can contain GC allocated data
375 tramp-x86.c
376         No variables which can contain GC allocated data
377
378
379 io-layer/
380 ---------
381 atomic.c
382         No variables which can contain GC allocated data
383 context.c
384         No variables which can contain GC allocated data
385 critical-sections.c
386         No variables which can contain GC allocated data
387 daemon.c
388         No variables which can contain GC allocated data
389 daemon-messages.c
390         No variables which can contain GC allocated data
391 error.c
392         No variables which can contain GC allocated data
393 events.c
394         No variables which can contain GC allocated data
395 handles.c
396         No variables which can contain GC allocated data
397 io.c
398         No variables which can contain GC allocated data
399 io-layer-dummy.c
400         No variables which can contain GC allocated data
401 misc.c
402         No variables which can contain GC allocated data
403 mono-mutex.c
404         No variables which can contain GC allocated data
405 mutexes.c
406         No variables which can contain GC allocated data
407 processes.c
408         No variables which can contain GC allocated data
409 security.c
410         No variables which can contain GC allocated data
411 semaphores.c
412         No variables which can contain GC allocated data
413 shared.c
414         No variables which can contain GC allocated data
415 sockets.c
416         No variables which can contain GC allocated data
417 system.c
418         No variables which can contain GC allocated data
419 threads.c
420         static MonoGHashTable *tls_gc_hash = NULL;
421                 added as a root
422         No other variables contain GC allocated data.
423         
424 timed-thread.c
425         No variables which can contain GC allocated data
426 timefuncs.c
427         No variables which can contain GC allocated data
428 wait.c
429         No variables which can contain GC allocated data
430
431
432