From 7ca713e156d455ce3fbe84890b278f14c6def34f Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Fri, 7 Mar 2014 10:25:23 -0500 Subject: [PATCH] [sgen] Change the bridge interface to include richer type information on classes. 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 | 16 +++++++++------- mono/metadata/sgen-bridge.h | 15 +++++++++++++-- mono/metadata/sgen-gc.c | 8 +++++++- mono/metadata/sgen-gc.h | 3 ++- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/mono/metadata/sgen-bridge.c b/mono/metadata/sgen-bridge.c index 774baa63bba..46c98eaa4c5 100644 --- a/mono/metadata/sgen-bridge.c +++ b/mono/metadata/sgen-bridge.c @@ -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); diff --git a/mono/metadata/sgen-bridge.h b/mono/metadata/sgen-bridge.h index 787418b7582..8bfeb09a6d7 100644 --- a/mono/metadata/sgen-bridge.h +++ b/mono/metadata/sgen-bridge.h @@ -29,9 +29,20 @@ 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*/ + 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; diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index 295168c311a..54e9ee24fc8 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -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; } diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index 21471a46474..b4b98778bfa 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -48,6 +48,7 @@ typedef struct _SgenThreadInfo SgenThreadInfo; #include #include #include +#include /* 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; -- 2.25.1