Merge pull request #2810 from kumpera/fix_hazard_free
[mono.git] / mono / metadata / sgen-bridge.h
1 /*
2  * Copyright 2011 Novell, Inc.
3  * 
4  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
5  */
6
7 /*
8  * The bridge is a mechanism for SGen to let clients override the death of some
9  * unreachable objects.  We use it in monodroid to do garbage collection across
10  * the Mono and Java heaps.
11  *
12  * The client can designate some objects as "bridged", which means that they
13  * participate in the bridge processing step once SGen considers them
14  * unreachable, i.e., dead.  Bridged objects must be registered for
15  * finalization.
16  *
17  * When SGen is done marking, it puts together a list of all dead bridged
18  * objects and then does a strongly connected component analysis over their
19  * object graph.  That graph will usually contain non-bridged objects, too.
20  *
21  * The output of the SCC analysis is passed to the `cross_references()`
22  * callback.  It is expected to set the `is_alive` flag on those strongly
23  * connected components that it wishes to be kept alive.  Only bridged objects
24  * will be reported to the callback, i.e., non-bridged objects are removed from
25  * the callback graph.
26  *
27  * In monodroid each bridged object has a corresponding Java mirror object.  In
28  * the bridge callback it reifies the Mono object graph in the Java heap so that
29  * the full, combined object graph is now instantiated on the Java side.  Then
30  * it triggers a Java GC, waits for it to finish, and checks which of the Java
31  * mirror objects are still alive.  For those it sets the `is_alive` flag and
32  * returns from the callback.
33  *
34  * The SCC analysis is done while the world is stopped, but the callback is made
35  * with the world running again.  Weak links to bridged objects and other
36  * objects reachable from them are kept until the callback returns, at which
37  * point all links to bridged objects that don't have `is_alive` set are nulled.
38  * Note that weak links to non-bridged objects reachable from bridged objects
39  * are not nulled.  This might be considered a bug.
40  */
41
42 #ifndef _MONO_SGEN_BRIDGE_H_
43 #define _MONO_SGEN_BRIDGE_H_
44
45 #include <mono/utils/mono-publib.h>
46
47 MONO_BEGIN_DECLS
48
49 enum {
50         SGEN_BRIDGE_VERSION = 4
51 };
52         
53 typedef enum {
54         /* Instances of this class should be scanned when computing the transitive dependency among bridges. E.g. List<object>*/
55         GC_BRIDGE_TRANSPARENT_CLASS,
56         /* Instances of this class should not be scanned when computing the transitive dependency among bridges. E.g. String*/
57         GC_BRIDGE_OPAQUE_CLASS,
58         /* Instances of this class should be bridged and have their dependency computed. */
59         GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS,
60         /* Instances of this class should be bridged but no dependencies should not be calculated. */
61         GC_BRIDGE_OPAQUE_BRIDGE_CLASS,
62 } MonoGCBridgeObjectKind;
63
64 typedef struct {
65         mono_bool is_alive;     /* to be set by the cross reference callback */
66         int num_objs;
67         MonoObject *objs [MONO_ZERO_LEN_ARRAY];
68 } MonoGCBridgeSCC;
69
70 typedef struct {
71         int src_scc_index;
72         int dst_scc_index;
73 } MonoGCBridgeXRef;
74
75 typedef struct {
76         int bridge_version;
77         /*
78          * Tells the runtime which classes to even consider when looking for
79          * bridged objects.  If subclasses are to be considered as well, the
80          * subclass check must be done in the callback.
81          */
82         MonoGCBridgeObjectKind (*bridge_class_kind) (MonoClass *klass);
83         /*
84          * This is only called on objects for whose classes
85          * `bridge_class_kind()` returned `XXX_BRIDGE_CLASS`.
86          */
87         mono_bool (*is_bridge_object) (MonoObject *object);
88         void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
89 } MonoGCBridgeCallbacks;
90
91 MONO_API void mono_gc_register_bridge_callbacks (MonoGCBridgeCallbacks *callbacks);
92
93 MONO_API void mono_gc_wait_for_bridge_processing (void);
94
95 MONO_END_DECLS
96
97 #endif