[sgen] Number of major objects marked in concurrent DTrace probes.
authorMark Probst <mark.probst@gmail.com>
Thu, 22 Nov 2012 12:11:35 +0000 (13:11 +0100)
committerMark Probst <mark.probst@gmail.com>
Sun, 9 Dec 2012 14:02:51 +0000 (15:02 +0100)
Can be enabled/disabled via #define in sgen-conf.h.  Disabled by default
because it's a small performance hit.

data/mono.d
mono/metadata/sgen-conf.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-marksweep.c

index c6447a2a0dbf70c0589890838e5339abb8e52075..bb42812b0d9c3c87df1a6f8fc5794763ba6c17ab 100644 (file)
@@ -20,10 +20,10 @@ provider mono {
        probe gc__end (int generation);
 
        probe gc__concurrent__start__begin (int generation);
-       probe gc__concurrent__start__end (int generation);
-       probe gc__concurrent__update__finish__begin (int generation);
-       probe gc__concurrent__update__end (int generation);
-       probe gc__concurrent__finish__end (int generation);
+       probe gc__concurrent__start__end (int generation, long long num_major_objects_marked);
+       probe gc__concurrent__update__finish__begin (int generation, long long num_major_objects_marked);
+       probe gc__concurrent__update__end (int generation, long long num_major_objects_marked);
+       probe gc__concurrent__finish__end (int generation, long long num_major_objects_marked);
 
        probe gc__sweep__begin (int generation, int full_sweep);
        probe gc__sweep__end (int generation, int full_sweep);
index d294a2efb0a07a1f800d77762bd3a44266775a6b..808e266c3ded65a9f3cfdf1110f793437e6c09d2 100644 (file)
@@ -75,6 +75,13 @@ typedef guint64 mword;
  */
 //#define XDOMAIN_CHECKS_IN_WBARRIER
 
+/*
+ * Define this to get number of objects marked information in the
+ * concurrent GC DTrace probes.  Has a small performance impact, so
+ * it's disabled by default.
+ */
+//#define SGEN_COUNT_NUMBER_OF_MAJOR_OBJECTS_MARKED
+
 #ifndef SGEN_BINARY_PROTOCOL
 #ifndef HEAVY_STATISTICS
 #define MANAGED_ALLOCATION
index 1987d58d418789176f9dc27ee0717e30bf85e8a3..eaa48fe99cba0b52759dc14bc3d9b9aa1283c8fd 100644 (file)
@@ -3079,6 +3079,11 @@ major_do_collection (const char *reason)
        TV_DECLARE (all_btv);
        int old_next_pin_slot;
 
+       if (major_collector.get_and_reset_num_major_objects_marked) {
+               long long num_marked = major_collector.get_and_reset_num_major_objects_marked ();
+               g_assert (!num_marked);
+       }
+
        /* world must be stopped already */
        TV_GETTIME (all_atv);
 
@@ -3088,6 +3093,10 @@ major_do_collection (const char *reason)
        TV_GETTIME (all_btv);
        gc_stats.major_gc_time_usecs += TV_ELAPSED (all_atv, all_btv);
 
+       /* FIXME: also report this to the user, preferably in gc-end. */
+       if (major_collector.get_and_reset_num_major_objects_marked)
+               major_collector.get_and_reset_num_major_objects_marked ();
+
        return bytes_pinned_from_failed_allocation > 0;
 }
 
@@ -3096,6 +3105,10 @@ static gboolean major_do_collection (const char *reason);
 static void
 major_start_concurrent_collection (const char *reason)
 {
+       long long num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
+
+       g_assert (num_objects_marked == 0);
+
        MONO_GC_CONCURRENT_START_BEGIN (GENERATION_OLD);
 
        // FIXME: store reason and pass it when finishing
@@ -3104,7 +3117,8 @@ major_start_concurrent_collection (const char *reason)
        gray_queue_redirect (&gray_queue);
        sgen_workers_wait_for_jobs ();
 
-       MONO_GC_CONCURRENT_START_END (GENERATION_OLD);
+       num_objects_marked = major_collector.get_and_reset_num_major_objects_marked ();
+       MONO_GC_CONCURRENT_START_END (GENERATION_OLD, num_objects_marked);
 
        current_collection_generation = -1;
 }
@@ -3112,7 +3126,7 @@ major_start_concurrent_collection (const char *reason)
 static gboolean
 major_update_or_finish_concurrent_collection (gboolean force_finish)
 {
-       MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD);
+       MONO_GC_CONCURRENT_UPDATE_FINISH_BEGIN (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
 
        g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
        if (!have_non_collection_major_object_remembers)
@@ -3122,7 +3136,7 @@ major_update_or_finish_concurrent_collection (gboolean force_finish)
        sgen_los_update_cardtable_mod_union ();
 
        if (!force_finish && !sgen_workers_all_done ()) {
-               MONO_GC_CONCURRENT_UPDATE_END (GENERATION_OLD);
+               MONO_GC_CONCURRENT_UPDATE_END (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
                return FALSE;
        }
 
@@ -3132,7 +3146,7 @@ major_update_or_finish_concurrent_collection (gboolean force_finish)
        current_collection_generation = GENERATION_OLD;
        major_finish_collection ("finishing", -1, TRUE);
 
-       MONO_GC_CONCURRENT_FINISH_END (GENERATION_OLD);
+       MONO_GC_CONCURRENT_FINISH_END (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
 
        current_collection_generation = -1;
 
index 61b1382ef77017e719743acec70237f4d2ae7600..6233786c6851d32c6a9df1a8bff2d498b0216184 100644 (file)
@@ -720,6 +720,7 @@ struct _SgenMajorCollector {
        void (*reset_worker_data) (void *data);
        gboolean (*is_valid_object) (char *object);
        gboolean (*describe_pointer) (char *pointer);
+       long long (*get_and_reset_num_major_objects_marked) (void);
 };
 
 extern SgenMajorCollector major_collector;
index 92cb98bf3630fa870db5c1ab9ed1277b26edc0d1..3a7fcf7747d4881e117f3927ec2a1ddce9f3f056 100644 (file)
@@ -219,6 +219,14 @@ static long long stat_major_blocks_freed = 0;
 static long long stat_major_blocks_lazy_swept = 0;
 static long long stat_major_objects_evacuated = 0;
 
+static long long num_major_objects_marked = 0;
+
+#ifdef SGEN_COUNT_NUMBER_OF_MAJOR_OBJECTS_MARKED
+#define INC_NUM_MAJOR_OBJECTS_MARKED() (++num_major_objects_marked)
+#else
+#define INC_NUM_MAJOR_OBJECTS_MARKED()
+#endif
+
 static void
 sweep_block (MSBlockInfo *block);
 
@@ -712,6 +720,7 @@ alloc_obj (MonoVTable *vtable, int size, gboolean pinned, gboolean has_reference
                MS_CALC_MARK_BIT (word, bit, obj);
                MS_SET_MARK_BIT (block, word, bit);
                binary_protocol_mark (obj, NULL, size);
+               INC_NUM_MAJOR_OBJECTS_MARKED ();
        }
 #endif
 
@@ -1023,6 +1032,7 @@ major_dump_heap (FILE *heap_dump_file)
                        if ((block)->has_references)                    \
                                GRAY_OBJECT_ENQUEUE ((queue), (obj));   \
                        binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+                       INC_NUM_MAJOR_OBJECTS_MARKED ();                \
                }                                                       \
        } while (0)
 #define MS_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do {               \
@@ -1034,6 +1044,7 @@ major_dump_heap (FILE *heap_dump_file)
                        if ((block)->has_references)                    \
                                GRAY_OBJECT_ENQUEUE ((queue), (obj));   \
                        binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+                       INC_NUM_MAJOR_OBJECTS_MARKED ();                \
                }                                                       \
        } while (0)
 #define MS_PAR_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do {           \
@@ -1046,6 +1057,7 @@ major_dump_heap (FILE *heap_dump_file)
                        if ((block)->has_references)                    \
                                GRAY_OBJECT_ENQUEUE ((queue), (obj));   \
                        binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \
+                       INC_NUM_MAJOR_OBJECTS_MARKED ();                \
                }                                                       \
        } while (0)
 
@@ -1252,6 +1264,7 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue)
                        sgen_los_pin_object (obj);
                        /* FIXME: only enqueue if object has references */
                        GRAY_OBJECT_ENQUEUE (queue, obj);
+                       INC_NUM_MAJOR_OBJECTS_MARKED ();
                }
        }
 }
@@ -1391,6 +1404,16 @@ major_copy_or_mark_object (void **ptr, SgenGrayQueue *queue)
 #endif
 #endif
 
+#ifdef SGEN_CONCURRENT_MARK
+static long long
+major_get_and_reset_num_major_objects_marked (void)
+{
+       long long num = num_major_objects_marked;
+       num_major_objects_marked = 0;
+       return num;
+}
+#endif
+
 #include "sgen-major-scan-object.h"
 
 static void
@@ -2278,6 +2301,7 @@ sgen_marksweep_init
 #endif
 #ifdef SGEN_CONCURRENT_MARK
        collector->is_concurrent = TRUE;
+       collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked;
 #else
        collector->is_concurrent = FALSE;
 #endif