From 35f397edc8526dafa31ad09ac5376504cdc41260 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Tue, 21 Jan 2014 14:36:15 -0800 Subject: [sgen] Count cards for binary protocol. --- mono/metadata/sgen-gc.h | 2 ++ mono/metadata/sgen-los.c | 27 +++++++++++++++++++++++++++ mono/metadata/sgen-marksweep.c | 26 ++++++++++++++++++++++++++ mono/metadata/sgen-protocol.c | 24 ++++++++++++++++++++---- mono/metadata/sgen-protocol.h | 27 +++++++++++++++++++++++++-- mono/metadata/sgen-stw.c | 18 ++++++++++++++++++ tools/sgen/sgen-grep-binprot.c | 30 ++++++++++++++++++++++++------ 7 files changed, 142 insertions(+), 12 deletions(-) diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index 2651412a255..9ded8a5308c 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -689,6 +689,7 @@ struct _SgenMajorCollector { MonoVTable* (*describe_pointer) (char *pointer); guint8* (*get_cardtable_mod_union_for_object) (char *object); long long (*get_and_reset_num_major_objects_marked) (void); + void (*count_cards) (long long *num_total_cards, long long *num_marked_cards); }; extern SgenMajorCollector major_collector; @@ -891,6 +892,7 @@ void sgen_los_iterate_objects (IterateObjectCallbackFunc cb, void *user_data) MO void sgen_los_iterate_live_block_ranges (sgen_cardtable_block_callback callback) MONO_INTERNAL; void sgen_los_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) MONO_INTERNAL; void sgen_los_update_cardtable_mod_union (void) MONO_INTERNAL; +void sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards) MONO_INTERNAL; void sgen_major_collector_scan_card_table (SgenGrayQueue *queue) MONO_INTERNAL; gboolean sgen_los_is_valid_object (char *object) MONO_INTERNAL; gboolean mono_sgen_los_describe_pointer (char *ptr) MONO_INTERNAL; diff --git a/mono/metadata/sgen-los.c b/mono/metadata/sgen-los.c index f8b1b25f9c4..c04da2545f5 100644 --- a/mono/metadata/sgen-los.c +++ b/mono/metadata/sgen-los.c @@ -564,6 +564,33 @@ sgen_los_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) } } +void +sgen_los_count_cards (long long *num_total_cards, long long *num_marked_cards) +{ + LOSObject *obj; + long long total_cards = 0; + long long marked_cards = 0; + + for (obj = los_object_list; obj; obj = obj->next) { + int i; + guint8 *cards = sgen_card_table_get_card_scan_address ((mword) obj->data); + guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + obj->size - 1); + mword num_cards = (cards_end - cards) + 1; + + if (!SGEN_OBJECT_HAS_REFERENCES (obj->data)) + continue; + + total_cards += num_cards; + for (i = 0; i < num_cards; ++i) { + if (cards [i]) + ++marked_cards; + } + } + + *num_total_cards = total_cards; + *num_marked_cards = marked_cards; +} + void sgen_los_update_cardtable_mod_union (void) { diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c index 0020d6c398b..d7c0a6057cc 100755 --- a/mono/metadata/sgen-marksweep.c +++ b/mono/metadata/sgen-marksweep.c @@ -2377,6 +2377,31 @@ major_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) } END_FOREACH_BLOCK; } +static void +major_count_cards (long long *num_total_cards, long long *num_marked_cards) +{ + MSBlockInfo *block; + long long total_cards = 0; + long long marked_cards = 0; + + FOREACH_BLOCK (block) { + guint8 *cards = sgen_card_table_get_card_scan_address ((mword) block->block); + int i; + + if (!block->has_references) + continue; + + total_cards += CARDS_PER_BLOCK; + for (i = 0; i < CARDS_PER_BLOCK; ++i) { + if (cards [i]) + ++marked_cards; + } + } END_FOREACH_BLOCK; + + *num_total_cards = total_cards; + *num_marked_cards = marked_cards; +} + #ifdef SGEN_HAVE_CONCURRENT_MARK static void update_cardtable_mod_union (void) @@ -2600,6 +2625,7 @@ sgen_marksweep_fixed_init (SgenMajorCollector *collector) collector->post_param_init = post_param_init; collector->is_valid_object = major_is_valid_object; collector->describe_pointer = major_describe_pointer; + collector->count_cards = major_count_cards; collector->major_ops.copy_or_mark_object = major_copy_or_mark_object_canonical; collector->major_ops.scan_object = major_scan_object; diff --git a/mono/metadata/sgen-protocol.c b/mono/metadata/sgen-protocol.c index 3863fb89cc2..ce0ac028cf9 100644 --- a/mono/metadata/sgen-protocol.c +++ b/mono/metadata/sgen-protocol.c @@ -245,15 +245,31 @@ binary_protocol_concurrent_update_finish (void) void binary_protocol_world_stopping (long long timestamp) { - SGenProtocolWorldStop entry = { timestamp }; - protocol_entry (SGEN_PROTOCOL_WORLD_STOPPING, &entry, sizeof (SGenProtocolWorldStop)); + SGenProtocolWorldStopping entry = { timestamp }; + protocol_entry (SGEN_PROTOCOL_WORLD_STOPPING, &entry, sizeof (SGenProtocolWorldStopping)); +} + +void +binary_protocol_world_stopped (long long timestamp, long long total_major_cards, + long long marked_major_cards, long long total_los_cards, long long marked_los_cards) +{ + SGenProtocolWorldStopped entry = { timestamp, total_major_cards, marked_major_cards, total_los_cards, marked_los_cards }; + protocol_entry (SGEN_PROTOCOL_WORLD_STOPPED, &entry, sizeof (SGenProtocolWorldStopped)); +} + +void +binary_protocol_world_restarting (int generation, long long timestamp, + long long total_major_cards, long long marked_major_cards, long long total_los_cards, long long marked_los_cards) +{ + SGenProtocolWorldRestarting entry = { generation, timestamp, total_major_cards, marked_major_cards, total_los_cards, marked_los_cards }; + protocol_entry (SGEN_PROTOCOL_WORLD_RESTARTING, &entry, sizeof (SGenProtocolWorldRestarting)); } void binary_protocol_world_restarted (int generation, long long timestamp) { - SGenProtocolWorldRestart entry = { generation, timestamp }; - protocol_entry (SGEN_PROTOCOL_WORLD_RESTARTED, &entry, sizeof (SGenProtocolWorldRestart)); + SGenProtocolWorldRestarted entry = { generation, timestamp }; + protocol_entry (SGEN_PROTOCOL_WORLD_RESTARTED, &entry, sizeof (SGenProtocolWorldRestarted)); } void diff --git a/mono/metadata/sgen-protocol.h b/mono/metadata/sgen-protocol.h index 4ad540809d5..1e7222c8b30 100644 --- a/mono/metadata/sgen-protocol.h +++ b/mono/metadata/sgen-protocol.h @@ -29,6 +29,8 @@ enum { SGEN_PROTOCOL_CONCURRENT_START, SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH, SGEN_PROTOCOL_WORLD_STOPPING, + SGEN_PROTOCOL_WORLD_STOPPED, + SGEN_PROTOCOL_WORLD_RESTARTING, SGEN_PROTOCOL_WORLD_RESTARTED, SGEN_PROTOCOL_ALLOC, SGEN_PROTOCOL_COPY, @@ -68,12 +70,29 @@ typedef struct { typedef struct { long long timestamp; -} SGenProtocolWorldStop; +} SGenProtocolWorldStopping; + +typedef struct { + long long timestamp; + long long total_major_cards; + long long marked_major_cards; + long long total_los_cards; + long long marked_los_cards; +} SGenProtocolWorldStopped; + +typedef struct { + int generation; + long long timestamp; + long long total_major_cards; + long long marked_major_cards; + long long total_los_cards; + long long marked_los_cards; +} SGenProtocolWorldRestarting; typedef struct { int generation; long long timestamp; -} SGenProtocolWorldRestart; +} SGenProtocolWorldRestarted; typedef struct { gpointer obj; @@ -215,6 +234,10 @@ void binary_protocol_collection_end (int index, int generation) MONO_INTERNAL; void binary_protocol_concurrent_start (void) MONO_INTERNAL; void binary_protocol_concurrent_update_finish (void) MONO_INTERNAL; void binary_protocol_world_stopping (long long timestamp) MONO_INTERNAL; +void binary_protocol_world_stopped (long long timestamp, long long total_major_cards, + long long marked_major_cards, long long total_los_cards, long long marked_los_cards) MONO_INTERNAL; +void binary_protocol_world_restarting (int generation, long long timestamp, + long long total_major_cards, long long marked_major_cards, long long total_los_cards, long long marked_los_cards) MONO_INTERNAL; void binary_protocol_world_restarted (int generation, long long timestamp) MONO_INTERNAL; void binary_protocol_thread_suspend (gpointer thread, gpointer stopped_ip) MONO_INTERNAL; diff --git a/mono/metadata/sgen-stw.c b/mono/metadata/sgen-stw.c index 75f71d02bc8..97480d5395a 100755 --- a/mono/metadata/sgen-stw.c +++ b/mono/metadata/sgen-stw.c @@ -191,6 +191,13 @@ release_gc_locks (void) UNLOCK_INTERRUPTION; } +static void +count_cards (long long *major_total, long long *major_marked, long long *los_total, long long *los_marked) +{ + sgen_get_major_collector ()->count_cards (major_total, major_marked); + sgen_los_count_cards (los_total, los_marked); +} + static TV_DECLARE (stop_world_time); static unsigned long max_pause_usec = 0; @@ -222,6 +229,11 @@ sgen_stop_world (int generation) SGEN_LOG (3, "world stopped %d thread(s)", count); mono_profiler_gc_event (MONO_GC_EVENT_POST_STOP_WORLD, generation); MONO_GC_WORLD_STOP_END (); + if (binary_protocol_is_enabled ()) { + long long major_total, major_marked, los_total, los_marked; + count_cards (&major_total, &major_marked, &los_total, &los_marked); + binary_protocol_world_stopped (sgen_timestamp (), major_total, major_marked, los_total, los_marked); + } sgen_memgov_collection_start (generation); sgen_bridge_reset_data (); @@ -239,6 +251,12 @@ sgen_restart_world (int generation, GGTimingInfo *timing) TV_DECLARE (end_bridge); unsigned long usec, bridge_usec; + if (binary_protocol_is_enabled ()) { + long long major_total, major_marked, los_total, los_marked; + count_cards (&major_total, &major_marked, &los_total, &los_marked); + binary_protocol_world_restarting (generation, sgen_timestamp (), major_total, major_marked, los_total, los_marked); + } + /* notify the profiler of the leftovers */ /* FIXME this is the wrong spot at we can STW for non collection reasons. */ if (G_UNLIKELY (mono_profiler_events & MONO_PROFILE_GC_MOVES)) diff --git a/tools/sgen/sgen-grep-binprot.c b/tools/sgen/sgen-grep-binprot.c index 787e033cadb..5d501b39cc7 100644 --- a/tools/sgen/sgen-grep-binprot.c +++ b/tools/sgen/sgen-grep-binprot.c @@ -27,8 +27,10 @@ read_entry (FILE *in, void **data) case SGEN_PROTOCOL_COLLECTION_END: size = sizeof (SGenProtocolCollection); break; case SGEN_PROTOCOL_CONCURRENT_START: size = 0; break; case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH: size = 0; break; - case SGEN_PROTOCOL_WORLD_STOPPING: size = sizeof (SGenProtocolWorldStop); break; - case SGEN_PROTOCOL_WORLD_RESTARTED: size = sizeof (SGenProtocolWorldRestart); break; + case SGEN_PROTOCOL_WORLD_STOPPING: size = sizeof (SGenProtocolWorldStopping); break; + case SGEN_PROTOCOL_WORLD_STOPPED: size = sizeof (SGenProtocolWorldStopped); break; + case SGEN_PROTOCOL_WORLD_RESTARTING: size = sizeof (SGenProtocolWorldRestarting); break; + case SGEN_PROTOCOL_WORLD_RESTARTED: size = sizeof (SGenProtocolWorldRestarted); break; case SGEN_PROTOCOL_ALLOC: size = sizeof (SGenProtocolAlloc); break; case SGEN_PROTOCOL_ALLOC_PINNED: size = sizeof (SGenProtocolAlloc); break; case SGEN_PROTOCOL_ALLOC_DEGRADED: size = sizeof (SGenProtocolAlloc); break; @@ -99,12 +101,26 @@ print_entry (int type, void *data) break; } case SGEN_PROTOCOL_WORLD_STOPPING: { - SGenProtocolWorldStop *entry = data; + SGenProtocolWorldStopping *entry = data; printf ("%s world stopping timestamp %lld\n", WORKER_PREFIX (type), entry->timestamp); break; } + case SGEN_PROTOCOL_WORLD_STOPPED: { + SGenProtocolWorldStopped *entry = data; + long long total = entry->total_major_cards + entry->total_los_cards; + long long marked = entry->marked_major_cards + entry->marked_los_cards; + printf ("%s world stopped timestamp %lld total %lld marked %lld %0.2f%%\n", WORKER_PREFIX (type), entry->timestamp, total, marked, 100.0 * (double) marked / (double) total); + break; + } + case SGEN_PROTOCOL_WORLD_RESTARTING: { + SGenProtocolWorldRestarting *entry = data; + long long total = entry->total_major_cards + entry->total_los_cards; + long long marked = entry->marked_major_cards + entry->marked_los_cards; + printf ("%s world restarting generation %d timestamp %lld total %lld marked %lld %0.2f%%\n", WORKER_PREFIX (type), entry->generation, entry->timestamp, total, marked, 100.0 * (double) marked / (double) total); + break; + } case SGEN_PROTOCOL_WORLD_RESTARTED: { - SGenProtocolWorldRestart *entry = data; + SGenProtocolWorldRestarted *entry = data; printf ("%s world restarted generation %d timestamp %lld\n", WORKER_PREFIX (type), entry->generation, entry->timestamp); break; } @@ -268,6 +284,8 @@ is_match (gpointer ptr, int type, void *data) case SGEN_PROTOCOL_CONCURRENT_START: case SGEN_PROTOCOL_CONCURRENT_UPDATE_FINISH: case SGEN_PROTOCOL_WORLD_STOPPING: + case SGEN_PROTOCOL_WORLD_STOPPED: + case SGEN_PROTOCOL_WORLD_RESTARTING: case SGEN_PROTOCOL_WORLD_RESTARTED: case SGEN_PROTOCOL_THREAD_SUSPEND: case SGEN_PROTOCOL_THREAD_RESTART: @@ -446,7 +464,7 @@ main (int argc, char *argv[]) if (pause_times) { switch (type) { case SGEN_PROTOCOL_WORLD_STOPPING: { - SGenProtocolWorldStop *entry = data; + SGenProtocolWorldStopping *entry = data; assert (!pause_times_stopped); pause_times_concurrent = FALSE; pause_times_ts = entry->timestamp; @@ -458,7 +476,7 @@ main (int argc, char *argv[]) pause_times_concurrent = TRUE; break; case SGEN_PROTOCOL_WORLD_RESTARTED: { - SGenProtocolWorldRestart *entry = data; + SGenProtocolWorldRestarted *entry = data; assert (pause_times_stopped); printf ("pause-time %d %d %lld %lld\n", entry->generation, -- cgit v1.2.3