Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Probst <mark.probst@gmail.com>2014-01-22 02:36:15 +0400
committerMark Probst <mark.probst@gmail.com>2014-04-17 01:18:15 +0400
commit35f397edc8526dafa31ad09ac5376504cdc41260 (patch)
tree33559042a3bf6bfaf9a90d5c89f6f9b4de34d99a
parent9f6ab33462d2ea539d3a9b9c9e686b8cc4ab394e (diff)
[sgen] Count cards for binary protocol.
-rw-r--r--mono/metadata/sgen-gc.h2
-rw-r--r--mono/metadata/sgen-los.c27
-rwxr-xr-xmono/metadata/sgen-marksweep.c26
-rw-r--r--mono/metadata/sgen-protocol.c24
-rw-r--r--mono/metadata/sgen-protocol.h27
-rwxr-xr-xmono/metadata/sgen-stw.c18
-rw-r--r--tools/sgen/sgen-grep-binprot.c30
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
@@ -565,6 +565,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)
{
LOSObject *obj;
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,