diff options
author | Mark Probst <mark.probst@gmail.com> | 2012-11-22 16:11:35 +0400 |
---|---|---|
committer | Mark Probst <mark.probst@gmail.com> | 2012-12-09 18:02:51 +0400 |
commit | 1382657aed319e627e816e5b6151fb44631cbcd2 (patch) | |
tree | 4704b6686bb8b337ebbd0bdaa34286fe42eb1ffc | |
parent | 08cbcd7f0261275fac6330235d9a04f285f9a759 (diff) |
[sgen] Number of major objects marked in concurrent DTrace probes.
Can be enabled/disabled via #define in sgen-conf.h. Disabled by default
because it's a small performance hit.
-rw-r--r-- | data/mono.d | 8 | ||||
-rw-r--r-- | mono/metadata/sgen-conf.h | 7 | ||||
-rw-r--r-- | mono/metadata/sgen-gc.c | 22 | ||||
-rw-r--r-- | mono/metadata/sgen-gc.h | 1 | ||||
-rw-r--r-- | mono/metadata/sgen-marksweep.c | 24 |
5 files changed, 54 insertions, 8 deletions
diff --git a/data/mono.d b/data/mono.d index c6447a2a0db..bb42812b0d9 100644 --- a/data/mono.d +++ b/data/mono.d @@ -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); diff --git a/mono/metadata/sgen-conf.h b/mono/metadata/sgen-conf.h index d294a2efb0a..808e266c3de 100644 --- a/mono/metadata/sgen-conf.h +++ b/mono/metadata/sgen-conf.h @@ -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 diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index 1987d58d418..eaa48fe99cb 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -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; diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index 61b1382ef77..6233786c685 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -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; diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c index 92cb98bf363..3a7fcf7747d 100644 --- a/mono/metadata/sgen-marksweep.c +++ b/mono/metadata/sgen-marksweep.c @@ -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 |