Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'docs/gc-variables-in-c')
-rw-r--r--docs/gc-variables-in-c96
1 files changed, 96 insertions, 0 deletions
diff --git a/docs/gc-variables-in-c b/docs/gc-variables-in-c
new file mode 100644
index 00000000000..61a7802fc18
--- /dev/null
+++ b/docs/gc-variables-in-c
@@ -0,0 +1,96 @@
+ Handling GC allocated objects in C
+
+As part of an effort to improve our GC, we need to keep track
+precisely of where objects are stored, so we can incrementally move
+from the current conservative GC to a more advanced precise and moving GC.
+Previously, all global C variables were considered GC roots, but this makes
+the GC less efficient and increases the chances false references are found
+to GC memory, hence retaining more memory than needed.
+We need to tell the GC that some object is supposed to be kept alive
+as if it was referenced in a global variable.
+
+For Mono embedders
+------------------
+
+In C#, if you say:
+class T {
+ static object o;
+}
+
+Any object which is stored in `o' is considered to be alive -- it will
+not be collected. `o' is a member of the root set for the GC.
+
+However, in C code, this is not the case. If you have:
+
+static MonoObject* o = NULL;
+
+The object in `o' will *NOT* be scanned.
+
+If you need to store an object in a C variable and prevent it from being
+collected, you need to acquire a GC handle for it.
+
+ guint32 handle = mono_gchandle_new (my_object, TRUE);
+
+TRUE means the object will be pinned, so it won't move in memory
+when we'll use a moving GC. You can access the MonoObject* referenced by
+a handle with:
+
+ MonoObject* obj = mono_gchandle_get_target (handle);
+
+When you don't need the handle anymore you need to call:
+
+ mono_gchandle_free (handle);
+
+Note that if you assign a new object to the C var, you need to get a new
+handle, it's not enough to store a new object in the C var.
+
+So code that looked like this:
+
+ static MonoObject* o = NULL;
+ ...
+ o = mono_object_new (...);
+ /* use o */
+ ...
+ /* when done to allow the GC to collect o */
+ o = NULL;
+
+should now be changed to:
+
+ static guint32 o_handle;
+ ...
+ MonoObject *o = mono_object_new (...);
+ o_handle = mono_gchandle_new (o, TRUE);
+ /* use o or mono_gchandle_get_target (o_handle) */
+ ...
+ /* when done to allow the GC to collect o */
+ mono_gchandle_free (o_handle);
+
+
+For Mono runtime developers
+---------------------------
+
+There are two kinds of static vars used to store pointers to GC memory
+that we need to consider:
+*) objects
+*) other memory chunks allocated with GC_MALLOC().
+
+Objects should be dealt with the GC handle support as detailed above.
+Other items should register the static pointer as an area to be considered
+part of the root set with the following:
+
+ static gpointer my_gc_data = NULL;
+ ...
+ MONO_GC_REGISTER_ROOT (my_gc_data);
+ my_gc_data = GC_MALLOC (...);
+
+Note that this registration is not necessary for *LOCAL* variables,
+as they are stored on the stack. It is only necessary for global variables,
+as they are not a part of the GC's root set.
+
+Once you have done the MONO_GC_REGISTER_ROOT, the variable is just like
+a static variable in C#. To keep an object alive, you have the variable reference
+the GC memory, to remove the reference, set the variable to NULL.
+
+As we prepare the code for a precise GC, GC_MALLOC () will not be used anymore
+in this way in most cases: we'll have a mechanism to specify exactly where
+references to GC memory is stored. \ No newline at end of file