X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fsgen-pinning-stats.c;h=ae9249b718e48afe86eae3206f1fe7deb10c550c;hb=34b1c9dbaaf6e9e195d7197c72a13f59ae4ef6fa;hp=68871c75f6ad6b916dda988d7c87d8aabca67d48;hpb=952e6b2075098fa6aca44e95c871c990b6fdee2a;p=mono.git diff --git a/mono/metadata/sgen-pinning-stats.c b/mono/metadata/sgen-pinning-stats.c index 68871c75f6a..ae9249b718e 100644 --- a/mono/metadata/sgen-pinning-stats.c +++ b/mono/metadata/sgen-pinning-stats.c @@ -1,6 +1,7 @@ /* * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. + * Copyright 2011 Xamarin Inc (http://www.xamarin.com) * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -21,12 +22,14 @@ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -enum { - PIN_TYPE_STACK, - PIN_TYPE_STATIC_DATA, - PIN_TYPE_OTHER, - PIN_TYPE_MAX -}; + +#include "config.h" +#ifdef HAVE_SGEN_GC + +#include "metadata/sgen-gc.h" +#include "metadata/sgen-pinning.h" +#include "metadata/sgen-hash-table.h" + typedef struct _PinStatAddress PinStatAddress; struct _PinStatAddress { @@ -36,17 +39,22 @@ struct _PinStatAddress { PinStatAddress *right; }; -typedef struct _ObjectList ObjectList; -struct _ObjectList { - MonoObject *obj; - ObjectList *next; -}; +typedef struct { + gulong num_pins [PIN_TYPE_MAX]; +} PinnedClassEntry; + +typedef struct { + gulong num_remsets; +} GlobalRemsetClassEntry; static PinStatAddress *pin_stat_addresses = NULL; static size_t pinned_byte_counts [PIN_TYPE_MAX]; static ObjectList *pinned_objects = NULL; +static SgenHashTable pinned_class_hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_STATISTICS, INTERNAL_MEM_STAT_PINNED_CLASS, sizeof (PinnedClassEntry), g_str_hash, g_str_equal); +static SgenHashTable global_remset_class_hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_STATISTICS, INTERNAL_MEM_STAT_REMSET_CLASS, sizeof (GlobalRemsetClassEntry), g_str_hash, g_str_equal); + static void pin_stats_tree_free (PinStatAddress *node) { @@ -54,11 +62,11 @@ pin_stats_tree_free (PinStatAddress *node) return; pin_stats_tree_free (node->left); pin_stats_tree_free (node->right); - free_internal_mem (node, INTERNAL_MEM_STATISTICS); + sgen_free_internal_dynamic (node, sizeof (PinStatAddress), INTERNAL_MEM_STATISTICS); } -static void -pin_stats_reset (void) +void +sgen_pin_stats_reset (void) { int i; pin_stats_tree_free (pin_stat_addresses); @@ -67,13 +75,13 @@ pin_stats_reset (void) pinned_byte_counts [i] = 0; while (pinned_objects) { ObjectList *next = pinned_objects->next; - free_internal_mem (pinned_objects, INTERNAL_MEM_STATISTICS); + sgen_free_internal_dynamic (pinned_objects, sizeof (ObjectList), INTERNAL_MEM_STATISTICS); pinned_objects = next; } } -static void -pin_stats_register_address (char *addr, int pin_type) +void +sgen_pin_stats_register_address (char *addr, int pin_type) { PinStatAddress **node_ptr = &pin_stat_addresses; PinStatAddress *node; @@ -91,7 +99,7 @@ pin_stats_register_address (char *addr, int pin_type) node_ptr = &node->right; } - node = get_internal_mem (sizeof (PinStatAddress), INTERNAL_MEM_STATISTICS); + node = sgen_alloc_internal_dynamic (sizeof (PinStatAddress), INTERNAL_MEM_STATISTICS, TRUE); node->addr = addr; node->pin_types = pin_type_bit; node->left = node->right = NULL; @@ -120,13 +128,98 @@ pin_stats_count_object_from_tree (char *obj, size_t size, PinStatAddress *node, pin_stats_count_object_from_tree (obj, size, node->right, pin_types); } +static gpointer +lookup_class_entry (SgenHashTable *hash_table, MonoClass *class, gpointer empty_entry) +{ + char *name = g_strdup_printf ("%s.%s", class->name_space, class->name); + gpointer entry = sgen_hash_table_lookup (hash_table, name); + + if (entry) { + g_free (name); + } else { + sgen_hash_table_replace (hash_table, name, empty_entry, NULL); + entry = sgen_hash_table_lookup (hash_table, name); + } + + return entry; +} + static void -pin_stats_register_object (char *obj, size_t size) +register_class (MonoClass *class, int pin_types) +{ + PinnedClassEntry empty_entry; + PinnedClassEntry *entry; + int i; + + memset (&empty_entry, 0, sizeof (PinnedClassEntry)); + entry = lookup_class_entry (&pinned_class_hash_table, class, &empty_entry); + + for (i = 0; i < PIN_TYPE_MAX; ++i) { + if (pin_types & (1 << i)) + ++entry->num_pins [i]; + } +} + +void +sgen_pin_stats_register_object (char *obj, size_t size) { int pin_types = 0; - ObjectList *list = get_internal_mem (sizeof (ObjectList), INTERNAL_MEM_STATISTICS); + ObjectList *list; + + list = sgen_alloc_internal_dynamic (sizeof (ObjectList), INTERNAL_MEM_STATISTICS, TRUE); pin_stats_count_object_from_tree (obj, size, pin_stat_addresses, &pin_types); list->obj = (MonoObject*)obj; list->next = pinned_objects; pinned_objects = list; + + if (pin_types) + register_class (((MonoVTable*)SGEN_LOAD_VTABLE (obj))->klass, pin_types); } + +void +sgen_pin_stats_register_global_remset (char *obj) +{ + GlobalRemsetClassEntry empty_entry; + GlobalRemsetClassEntry *entry; + + memset (&empty_entry, 0, sizeof (GlobalRemsetClassEntry)); + entry = lookup_class_entry (&global_remset_class_hash_table, ((MonoVTable*)SGEN_LOAD_VTABLE (obj))->klass, &empty_entry); + + ++entry->num_remsets; +} + +void +sgen_pin_stats_print_class_stats (void) +{ + char *name; + PinnedClassEntry *pinned_entry; + GlobalRemsetClassEntry *remset_entry; + + g_print ("\n%-50s %10s %10s %10s\n", "Class", "Stack", "Static", "Other"); + SGEN_HASH_TABLE_FOREACH (&pinned_class_hash_table, name, pinned_entry) { + int i; + g_print ("%-50s", name); + for (i = 0; i < PIN_TYPE_MAX; ++i) + g_print (" %10ld", pinned_entry->num_pins [i]); + g_print ("\n"); + } SGEN_HASH_TABLE_FOREACH_END; + + g_print ("\n%-50s %10s\n", "Class", "#Remsets"); + SGEN_HASH_TABLE_FOREACH (&global_remset_class_hash_table, name, remset_entry) { + g_print ("%-50s %10ld\n", name, remset_entry->num_remsets); + } SGEN_HASH_TABLE_FOREACH_END; +} + +size_t +sgen_pin_stats_get_pinned_byte_count (int pin_type) +{ + return pinned_byte_counts [pin_type]; +} + +ObjectList* +sgen_pin_stats_get_object_list (void) +{ + return pinned_objects; +} + +#endif /* HAVE_SGEN_GC */