Skip to content

Commit

Permalink
[sgen] Add stats for allocated gchandles (mono/mono#17074)
Browse files Browse the repository at this point in the history
Commit migrated from mono/mono@eb887a8
  • Loading branch information
BrzVlad authored Sep 30, 2019
1 parent e417bcf commit 2457a56
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/mono/mono/sgen/sgen-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1786,6 +1786,7 @@ collect_nursery (const char *reason, gboolean is_overflow)
SGEN_LOG (2, "Old generation scan: %lld usecs", (long long)(TV_ELAPSED (atv, btv) / 10));

sgen_pin_stats_report ();
sgen_gchandle_stats_report ();

TV_GETTIME (atv);
time_minor_scan_pinned += TV_ELAPSED (btv, atv);
Expand Down Expand Up @@ -3611,6 +3612,8 @@ sgen_gc_init (void)
debug_print_allowance = TRUE;
} else if (!strcmp (opt, "print-pinning")) {
sgen_pin_stats_enable ();
} else if (!strcmp (opt, "print-gchandles")) {
sgen_gchandle_stats_enable ();
} else if (!strcmp (opt, "verify-before-allocs")) {
sgen_verify_before_allocs = 1;
sgen_has_per_allocation_action = TRUE;
Expand Down Expand Up @@ -3719,6 +3722,7 @@ sgen_gc_init (void)
fprintf (stderr, " check-scan-starts\n");
fprintf (stderr, " print-allowance\n");
fprintf (stderr, " print-pinning\n");
fprintf (stderr, " print-gchandles\n");
fprintf (stderr, " heap-dump=<filename>\n");
fprintf (stderr, " binary-protocol=<filename>[:<file-size-limit>]\n");
fprintf (stderr, " nursery-canaries\n");
Expand Down
4 changes: 4 additions & 0 deletions src/mono/mono/sgen/sgen-gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ enum {
INTERNAL_MEM_STATISTICS,
INTERNAL_MEM_STAT_PINNED_CLASS,
INTERNAL_MEM_STAT_REMSET_CLASS,
INTERNAL_MEM_STAT_GCHANDLE_CLASS,
INTERNAL_MEM_GRAY_QUEUE,
INTERNAL_MEM_MS_TABLES,
INTERNAL_MEM_MS_BLOCK_INFO,
Expand Down Expand Up @@ -470,6 +471,9 @@ void sgen_pin_stats_register_object (GCObject *obj, int generation);
void sgen_pin_stats_register_global_remset (GCObject *obj);
void sgen_pin_stats_report (void);

void sgen_gchandle_stats_enable (void);
void sgen_gchandle_stats_report (void);

void sgen_sort_addresses (void **array, size_t size);
void sgen_add_to_global_remset (gpointer ptr, GCObject *obj);

Expand Down
83 changes: 83 additions & 0 deletions src/mono/mono/sgen/sgen-gchandles.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ static volatile guint32 stat_gc_handles_allocated = 0;
static volatile guint32 stat_gc_handles_max_allocated = 0;
#endif


typedef struct {
size_t num_handles [HANDLE_TYPE_MAX];
} GCHandleClassEntry;

static gboolean do_gchandle_stats = FALSE;

static SgenHashTable gchandle_class_hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_STATISTICS, INTERNAL_MEM_STAT_GCHANDLE_CLASS, sizeof (GCHandleClassEntry), g_str_hash, g_str_equal);

/*
* A table of GC handle data, implementing a simple lock-free bitmap allocator.
*
Expand Down Expand Up @@ -514,6 +523,80 @@ sgen_register_obj_with_weak_fields (GCObject *obj)
alloc_handle (gc_handles_for_type (HANDLE_WEAK_FIELDS), obj, FALSE);
}

void
sgen_gchandle_stats_enable (void)
{
do_gchandle_stats = TRUE;
}

static void
sgen_gchandle_stats_register_vtable (GCVTable vtable, int handle_type)
{
GCHandleClassEntry *entry;

char *name = g_strdup_printf ("%s.%s", sgen_client_vtable_get_namespace (vtable), sgen_client_vtable_get_name (vtable));
entry = (GCHandleClassEntry*) sgen_hash_table_lookup (&gchandle_class_hash_table, name);

if (entry) {
g_free (name);
} else {
// Create the entry for this class and get the address of it
GCHandleClassEntry empty_entry;
memset (&empty_entry, 0, sizeof (GCHandleClassEntry));
sgen_hash_table_replace (&gchandle_class_hash_table, name, &empty_entry, NULL);
entry = (GCHandleClassEntry*) sgen_hash_table_lookup (&gchandle_class_hash_table, name);
}

entry->num_handles [handle_type]++;
}

static void
sgen_gchandle_stats_count (void)
{
int i;

sgen_hash_table_clean (&gchandle_class_hash_table);

for (i = HANDLE_TYPE_MIN; i < HANDLE_TYPE_MAX; i++) {
HandleData *handles = gc_handles_for_type ((GCHandleType)i);
SgenArrayList *array = &handles->entries_array;
volatile gpointer *slot;
gpointer hidden, revealed;

SGEN_ARRAY_LIST_FOREACH_SLOT (array, slot) {
hidden = *slot;
revealed = MONO_GC_REVEAL_POINTER (hidden, MONO_GC_HANDLE_TYPE_IS_WEAK (i));

if (MONO_GC_HANDLE_IS_OBJECT_POINTER (hidden))
sgen_gchandle_stats_register_vtable (SGEN_LOAD_VTABLE (revealed), i);
} SGEN_ARRAY_LIST_END_FOREACH_SLOT;
}
}

void
sgen_gchandle_stats_report (void)
{
char *name;
GCHandleClassEntry *gchandle_entry;

if (!do_gchandle_stats)
return;

sgen_gchandle_stats_count ();

mono_gc_printf (sgen_gc_debug_file, "\n%-60s %10s %10s %10s\n", "Class", "Normal", "Weak", "Pinned");
SGEN_HASH_TABLE_FOREACH (&gchandle_class_hash_table, char *, name, GCHandleClassEntry *, gchandle_entry) {
mono_gc_printf (sgen_gc_debug_file, "%-60s", name);
mono_gc_printf (sgen_gc_debug_file, " %10ld", (long)gchandle_entry->num_handles [HANDLE_NORMAL]);
size_t weak_handles = gchandle_entry->num_handles [HANDLE_WEAK] +
gchandle_entry->num_handles [HANDLE_WEAK_TRACK] +
gchandle_entry->num_handles [HANDLE_WEAK_FIELDS];
mono_gc_printf (sgen_gc_debug_file, " %10ld", (long)weak_handles);
mono_gc_printf (sgen_gc_debug_file, " %10ld", (long)gchandle_entry->num_handles [HANDLE_PINNED]);
mono_gc_printf (sgen_gc_debug_file, "\n");
} SGEN_HASH_TABLE_FOREACH_END;
}

void
sgen_init_gchandles (void)
{
Expand Down
1 change: 1 addition & 0 deletions src/mono/mono/sgen/sgen-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ description_for_type (int type)
case INTERNAL_MEM_STATISTICS: return "statistics";
case INTERNAL_MEM_STAT_PINNED_CLASS: return "pinned-class";
case INTERNAL_MEM_STAT_REMSET_CLASS: return "remset-class";
case INTERNAL_MEM_STAT_GCHANDLE_CLASS: return "gchandle-class";
case INTERNAL_MEM_GRAY_QUEUE: return "gray-queue";
case INTERNAL_MEM_MS_TABLES: return "marksweep-tables";
case INTERNAL_MEM_MS_BLOCK_INFO: return "marksweep-block-info";
Expand Down

0 comments on commit 2457a56

Please sign in to comment.