[sgen] Change the bridge interface to include richer type information on classes.
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 7 Mar 2014 15:25:23 +0000 (10:25 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 7 Mar 2014 15:37:20 +0000 (10:37 -0500)
There is an additional axis to bridge processing than just if a type is a bridge or not.
It can be processing transparent or opaque.

We didn't make this distinction before and treated all types as transparent.

Opaque types means that bridge processing should stop at them. An opaque bridge, in
addition to that, means it should be reported in.

This change paves the way for bridge graph pruning.

mono/metadata/sgen-bridge.c
mono/metadata/sgen-bridge.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h

index 774baa63bba30fed831cd95b3d645e54b965ace1..46c98eaa4c59f5fe3e373214b1f98ce212811b6e 100644 (file)
@@ -308,10 +308,10 @@ sgen_is_bridge_object (MonoObject *obj)
        return bridge_callbacks.is_bridge_object (obj);
 }
 
-gboolean
-sgen_is_bridge_class (MonoClass *class)
+MonoGCBridgeObjectKind
+sgen_bridge_class_kind (MonoClass *class)
 {
-       return bridge_callbacks.is_bridge_class (class);
+       return bridge_callbacks.bridge_class_kind (class);
 }
 
 gboolean
@@ -840,10 +840,12 @@ sgen_bridge_describe_pointer (MonoObject *obj)
 
 static const char *bridge_class;
 
-static gboolean
-bridge_test_is_bridge_class (MonoClass *class)
+static MonoGCBridgeObjectKind
+bridge_test_bridge_class_kind (MonoClass *class)
 {
-       return !strcmp (bridge_class, class->name);
+       if (!strcmp (bridge_class, class->name))
+               return GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS;
+       return GC_BRIDGE_TRANSPARENT_CLASS;
 }
 
 static gboolean
@@ -956,7 +958,7 @@ sgen_register_test_bridge_callbacks (const char *bridge_class_name)
 {
        MonoGCBridgeCallbacks callbacks;
        callbacks.bridge_version = SGEN_BRIDGE_VERSION;
-       callbacks.is_bridge_class = bridge_test_is_bridge_class;
+       callbacks.bridge_class_kind = bridge_test_bridge_class_kind;
        callbacks.is_bridge_object = bridge_test_is_bridge_object;
        callbacks.cross_references = bridge_class_name[0] == '2' ? bridge_test_cross_reference2 : bridge_test_cross_reference;
        mono_gc_register_bridge_callbacks (&callbacks);
index 787418b7582de0f1c41031fb8a6fff37e6057365..8bfeb09a6d717af7a96f4ceeb1a03137c4e0519b 100644 (file)
 MONO_BEGIN_DECLS
 
 enum {
-       SGEN_BRIDGE_VERSION = 3
+       SGEN_BRIDGE_VERSION = 4
 };
        
+typedef enum {
+       /* Instances of this class should be scanned when computing the transitive dependency among bridges. E.g. List<object>*/
+       GC_BRIDGE_TRANSPARENT_CLASS,
+       /* Instances of this class should not be scanned when computing the transitive dependency among bridges. E.g. String*/
+       GC_BRIDGE_OPAQUE_CLASS,
+       /* Instances of this class should be bridged and have their dependency computed. */
+       GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS,
+       /* Instances of this class should be bridged but no dependencies should not be calculated. */
+       GC_BRIDGE_OPAQUE_BRIDGE_CLASS,
+} MonoGCBridgeObjectKind;
+
 typedef struct {
        mono_bool is_alive;     /* to be set by the cross reference callback */
        int num_objs;
@@ -45,7 +56,7 @@ typedef struct {
 
 typedef struct {
        int bridge_version;
-       mono_bool (*is_bridge_class) (MonoClass *class);
+       MonoGCBridgeObjectKind (*bridge_class_kind) (MonoClass *class);
        mono_bool (*is_bridge_object) (MonoObject *object);
        void (*cross_references) (int num_sccs, MonoGCBridgeSCC **sccs, int num_xrefs, MonoGCBridgeXRef *xrefs);
 } MonoGCBridgeCallbacks;
index 295168c311a673a7e1ae9d64ff650f2eec35afac..54e9ee24fc8fa36d0a420cd2fba0d333d6d8a6a7 100644 (file)
@@ -5634,8 +5634,14 @@ sgen_get_remset (void)
 guint
 mono_gc_get_vtable_bits (MonoClass *class)
 {
-       if (sgen_need_bridge_processing () && sgen_is_bridge_class (class))
+       /* FIXME move this to the bridge code */
+       if (!sgen_need_bridge_processing ())
+               return 0;
+       switch (sgen_bridge_class_kind (class)) {
+       case GC_BRIDGE_TRANSPARENT_BRIDGE_CLASS:
+       case GC_BRIDGE_OPAQUE_BRIDGE_CLASS:
                return SGEN_GC_BIT_BRIDGE_OBJECT;
+       }
        return 0;
 }
 
index 21471a4647421c8a10623e4389fce6ad9460b233..b4b98778bfaf24106cd2b3e91e6f319fb5d0f802 100644 (file)
@@ -48,6 +48,7 @@ typedef struct _SgenThreadInfo SgenThreadInfo;
 #include <mono/metadata/sgen-descriptor.h>
 #include <mono/metadata/sgen-gray.h>
 #include <mono/metadata/sgen-hash-table.h>
+#include <mono/metadata/sgen-bridge.h>
 
 /* The method used to clear the nursery */
 /* Clearing at nursery collections is the safest, but has bad interactions with caches.
@@ -791,7 +792,7 @@ void sgen_bridge_processing_stw_step (void) MONO_INTERNAL;
 void sgen_bridge_processing_finish (int generation) MONO_INTERNAL;
 void sgen_register_test_bridge_callbacks (const char *bridge_class_name) MONO_INTERNAL;
 gboolean sgen_is_bridge_object (MonoObject *obj) MONO_INTERNAL;
-gboolean sgen_is_bridge_class (MonoClass *class) MONO_INTERNAL;
+MonoGCBridgeObjectKind sgen_bridge_class_kind (MonoClass *class) MONO_INTERNAL;
 void sgen_mark_bridge_object (MonoObject *obj) MONO_INTERNAL;
 void sgen_bridge_register_finalized_object (MonoObject *object) MONO_INTERNAL;
 void sgen_bridge_describe_pointer (MonoObject *object) MONO_INTERNAL;