Skip to content

Instantly share code, notes, and snippets.

@luhenry
Created March 11, 2014 00:36
Show Gist options
  • Save luhenry/9477349 to your computer and use it in GitHub Desktop.
Save luhenry/9477349 to your computer and use it in GitHub Desktop.
diff --git a/mono/metadata/mono-perfcounters-def.h b/mono/metadata/mono-perfcounters-def.h
index e9510d5..7c4bbfe 100644
--- a/mono/metadata/mono-perfcounters-def.h
+++ b/mono/metadata/mono-perfcounters-def.h
@@ -34,92 +34,6 @@ PERFCTR_COUNTER(ASPNET_REQ_Q, "Requests Queued", "", NumberOfItems64, aspnet_req
PERFCTR_COUNTER(ASPNET_REQ_TOTAL, "Requests Total", "", NumberOfItems32, aspnet_requests)
PERFCTR_COUNTER(ASPNET_REQ_PSEC, "Requests/Sec", "", RateOfCountsPerSecond32, aspnet_requests)
-PERFCTR_CAT(JIT, ".NET CLR JIT", "", MultiInstance, Mono, JIT_BYTES)
-PERFCTR_COUNTER(JIT_BYTES, "# of IL Bytes JITted", "", NumberOfItems32, jit_bytes)
-PERFCTR_COUNTER(JIT_METHODS, "# of IL Methods JITted", "", NumberOfItems32, jit_methods)
-PERFCTR_COUNTER(JIT_TIME, "% Time in JIT", "", RawFraction, jit_time)
-PERFCTR_COUNTER(JIT_BYTES_PSEC, "IL Bytes Jitted/Sec", "", RateOfCountsPerSecond32, jit_bytes)
-PERFCTR_COUNTER(JIT_FAILURES, "Standard Jit Failures", "", NumberOfItems32, jit_failures)
-
-PERFCTR_CAT(EXC, ".NET CLR Exceptions", "", MultiInstance, Mono, EXC_THROWN)
-PERFCTR_COUNTER(EXC_THROWN, "# of Exceps Thrown", "", NumberOfItems32, exceptions_thrown)
-PERFCTR_COUNTER(EXC_THROWN_PSEC, "# of Exceps Thrown/Sec", "", RateOfCountsPerSecond32, exceptions_thrown)
-PERFCTR_COUNTER(EXC_FILTERS_PSEC, "# of Filters/Sec", "", RateOfCountsPerSecond32, exceptions_filters)
-PERFCTR_COUNTER(EXC_FINALLYS_PSEC, "# of Finallys/Sec", "", RateOfCountsPerSecond32, exceptions_finallys)
-PERFCTR_COUNTER(EXC_CATCH_DEPTH, "Throw to Catch Depth/Sec", "", NumberOfItems32, exceptions_depth)
-
-PERFCTR_CAT(GC, ".NET CLR Memory", "", MultiInstance, Mono, GC_GEN0)
-PERFCTR_COUNTER(GC_GEN0, "# Gen 0 Collections", "", NumberOfItems32, gc_collections0)
-PERFCTR_COUNTER(GC_GEN1, "# Gen 1 Collections", "", NumberOfItems32, gc_collections1)
-PERFCTR_COUNTER(GC_GEN2, "# Gen 2 Collections", "", NumberOfItems32, gc_collections2)
-PERFCTR_COUNTER(GC_PROM0, "Promoted Memory from Gen 0", "", NumberOfItems32, gc_promotions0)
-PERFCTR_COUNTER(GC_PROM1, "Promoted Memory from Gen 1", "", NumberOfItems32, gc_promotions1)
-PERFCTR_COUNTER(GC_PROM0SEC, "Gen 0 Promoted Bytes/Sec", "", RateOfCountsPerSecond32, gc_promotions0)
-PERFCTR_COUNTER(GC_PROM1SEC, "Gen 1 Promoted Bytes/Sec", "", RateOfCountsPerSecond32, gc_promotions1)
-PERFCTR_COUNTER(GC_PROMFIN, "Promoted Finalization-Memory from Gen 0", "", NumberOfItems32, gc_promotion_finalizers)
-PERFCTR_COUNTER(GC_GEN0SIZE, "Gen 0 heap size", "", NumberOfItems32, gc_gen0size)
-PERFCTR_COUNTER(GC_GEN1SIZE, "Gen 1 heap size", "", NumberOfItems32, gc_gen1size)
-PERFCTR_COUNTER(GC_GEN2SIZE, "Gen 2 heap size", "", NumberOfItems32, gc_gen2size)
-PERFCTR_COUNTER(GC_LOSIZE, "Large Object Heap size", "", NumberOfItems32, gc_lossize)
-PERFCTR_COUNTER(GC_FINSURV, "Finalization Survivors", "", NumberOfItems32, gc_fin_survivors)
-PERFCTR_COUNTER(GC_NHANDLES, "# GC Handles", "", NumberOfItems32, gc_num_handles)
-PERFCTR_COUNTER(GC_BYTESSEC, "Allocated Bytes/sec", "", RateOfCountsPerSecond32, gc_allocated)
-PERFCTR_COUNTER(GC_INDGC, "# Induced GC", "", NumberOfItems32, gc_induced)
-PERFCTR_COUNTER(GC_PERCTIME, "% Time in GC", "", RawFraction, gc_time)
-PERFCTR_COUNTER(GC_BYTES, "# Bytes in all Heaps", "", NumberOfItems32, gc_total_bytes)
-PERFCTR_COUNTER(GC_COMMBYTES, "# Total committed Bytes", "", NumberOfItems32, gc_committed_bytes)
-PERFCTR_COUNTER(GC_RESBYTES, "# Total reserved Bytes", "", NumberOfItems32, gc_reserved_bytes)
-PERFCTR_COUNTER(GC_PINNED, "# of Pinned Objects", "", NumberOfItems32, gc_num_pinned)
-PERFCTR_COUNTER(GC_SYNKB, "# of Sink Blocks in use", "", NumberOfItems32, gc_sync_blocks)
-
-PERFCTR_CAT(REMOTING, ".NET CLR Remoting", "", MultiInstance, Mono, REMOTING_CALLSEC)
-PERFCTR_COUNTER(REMOTING_CALLSEC, "Remote Calls/sec", "", RateOfCountsPerSecond32, remoting_calls)
-PERFCTR_COUNTER(REMOTING_CALLS, "Total Remote Calls", "", NumberOfItems32, remoting_calls)
-PERFCTR_COUNTER(REMOTING_CHANNELS, "Channels", "", NumberOfItems32, remoting_channels)
-PERFCTR_COUNTER(REMOTING_CPROXIES, "Context Proxies", "", NumberOfItems32, remoting_proxies)
-PERFCTR_COUNTER(REMOTING_CBLOADED, "Context-Bound Classes Loaded", "", NumberOfItems32, remoting_classes)
-PERFCTR_COUNTER(REMOTING_CBALLOCSEC, "Context-Bound Objects Alloc / sec", "", RateOfCountsPerSecond32, remoting_objects)
-PERFCTR_COUNTER(REMOTING_CONTEXTS, "Contexts", "", NumberOfItems32, remoting_contexts)
-
-PERFCTR_CAT(LOADING, ".NET CLR Loading", "", MultiInstance, Mono, LOADING_CLASSES)
-PERFCTR_COUNTER(LOADING_CLASSES, "Current Classes Loaded", "", NumberOfItems32, loader_classes)
-PERFCTR_COUNTER(LOADING_TOTCLASSES, "Total Classes Loaded", "", NumberOfItems32, loader_total_classes)
-PERFCTR_COUNTER(LOADING_CLASSESSEC, "Rate of Classes Loaded", "", RateOfCountsPerSecond32, loader_total_classes)
-PERFCTR_COUNTER(LOADING_APPDOMAINS, "Current appdomains", "", NumberOfItems32, loader_appdomains)
-PERFCTR_COUNTER(LOADING_TOTAPPDOMAINS, "Total Appdomains", "", NumberOfItems32, loader_total_appdomains)
-PERFCTR_COUNTER(LOADING_APPDOMAINSEC, "Rate of appdomains", "", RateOfCountsPerSecond32, loader_total_appdomains)
-PERFCTR_COUNTER(LOADING_ASSEMBLIES, "Current Assemblies", "", NumberOfItems32, loader_assemblies)
-PERFCTR_COUNTER(LOADING_TOTASSEMBLIES, "Total Assemblies", "", NumberOfItems32, loader_total_assemblies)
-PERFCTR_COUNTER(LOADING_ASSEMBLIESEC, "Rate of Assemblies", "", RateOfCountsPerSecond32, loader_total_assemblies)
-PERFCTR_COUNTER(LOADING_FAILURES, "Total # of Load Failures", "", NumberOfItems32, loader_failures)
-PERFCTR_COUNTER(LOADING_FAILURESSEC, "Rate of Load Failures", "", RateOfCountsPerSecond32, loader_failures)
-PERFCTR_COUNTER(LOADING_BYTES, "Bytes in Loader Heap", "", NumberOfItems32, loader_bytes)
-PERFCTR_COUNTER(LOADING_APPUNLOADED, "Total appdomains unloaded", "", NumberOfItems32, loader_appdomains_uloaded)
-PERFCTR_COUNTER(LOADING_APPUNLOADEDSEC, "Rate of appdomains unloaded", "", RateOfCountsPerSecond32, loader_appdomains_uloaded)
-
-PERFCTR_CAT(THREAD, ".NET CLR LocksAndThreads", "", MultiInstance, Mono, THREAD_CONTENTIONS)
-PERFCTR_COUNTER(THREAD_CONTENTIONS, "Total # of Contentions", "", NumberOfItems32, thread_contentions)
-PERFCTR_COUNTER(THREAD_CONTENTIONSSEC, "Contention Rate / sec", "", RateOfCountsPerSecond32, thread_contentions)
-PERFCTR_COUNTER(THREAD_QUEUELEN, "Current Queue Length", "", NumberOfItems32, thread_queue_len)
-PERFCTR_COUNTER(THREAD_QUEUELENP, "Queue Length Peak", "", NumberOfItems32, thread_queue_max)
-PERFCTR_COUNTER(THREAD_QUEUELENSEC, "Queue Length / sec", "", RateOfCountsPerSecond32, thread_queue_max)
-PERFCTR_COUNTER(THREAD_NUMLOG, "# of current logical Threads", "", NumberOfItems32, thread_num_logical)
-PERFCTR_COUNTER(THREAD_NUMPHYS, "# of current physical Threads", "", NumberOfItems32, thread_num_physical)
-PERFCTR_COUNTER(THREAD_NUMREC, "# of current recognized threads", "", NumberOfItems32, thread_cur_recognized)
-PERFCTR_COUNTER(THREAD_TOTREC, "# of total recognized threads", "", NumberOfItems32, thread_num_recognized)
-PERFCTR_COUNTER(THREAD_TOTRECSEC, "rate of recognized threads / sec", "", RateOfCountsPerSecond32, thread_num_recognized)
-
-PERFCTR_CAT(INTEROP, ".NET CLR Interop", "", MultiInstance, Mono, INTEROP_NUMCCW)
-PERFCTR_COUNTER(INTEROP_NUMCCW, "# of CCWs", "", NumberOfItems32, interop_num_ccw)
-PERFCTR_COUNTER(INTEROP_STUBS, "# of Stubs", "", NumberOfItems32, interop_num_stubs)
-PERFCTR_COUNTER(INTEROP_MARSH, "# of marshalling", "", NumberOfItems32, interop_num_marshals)
-
-PERFCTR_CAT(SECURITY, ".NET CLR Security", "", MultiInstance, Mono, SECURITY_CHECKS)
-PERFCTR_COUNTER(SECURITY_CHECKS, "Total Runtime Checks", "", NumberOfItems32, security_num_checks)
-PERFCTR_COUNTER(SECURITY_LCHECKS, "# Link Time Checks", "", NumberOfItems32, security_num_link_checks)
-PERFCTR_COUNTER(SECURITY_PERCTIME, "% Time in RT checks", "", RawFraction, security_time)
-PERFCTR_COUNTER(SECURITY_SWDEPTH, "Stack Walk Depth", "", NumberOfItems32, security_depth)
-
PERFCTR_CAT(THREADPOOL, "Mono Threadpool", "", MultiInstance, Mono, THREADPOOL_WORKITEMS)
PERFCTR_COUNTER(THREADPOOL_WORKITEMS, "Work Items Added", "", NumberOfItems64, threadpool_workitems)
PERFCTR_COUNTER(THREADPOOL_WORKITEMS_PSEC, "Work Items Added/Sec", "", RateOfCountsPerSecond32, threadpool_workitems)
diff --git a/mono/metadata/mono-perfcounters.c b/mono/metadata/mono-perfcounters.c
index ec72516..df5deee 100644
--- a/mono/metadata/mono-perfcounters.c
+++ b/mono/metadata/mono-perfcounters.c
@@ -33,6 +33,7 @@
#include "metadata/object-internals.h"
/* for mono_stats */
#include "metadata/class-internals.h"
+#include "utils/mono-counters.h"
#include "utils/mono-time.h"
#include "utils/mono-mmap.h"
#include "utils/mono-proclib.h"
@@ -601,6 +602,17 @@ custom_category_counters (SharedCategory* cat)
return p;
}
+static GSList*
+get_counters_categories (void)
+{
+ int i;
+ GSList *list = NULL;
+ for (i = 0; mono_counters_categories[i]; i++) {
+ list = g_slist_append(list, mono_counters_categories[i]);
+ }
+ return list;
+};
+
static SharedCounter*
find_custom_counter (SharedCategory* cat, MonoString *name)
{
@@ -976,13 +988,6 @@ predef_writable_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounter
}
sample->counterType = predef_counters [predef_categories [cat_id].first_counter + id].type;
switch (cat_id) {
- case CATEGORY_EXC:
- switch (id) {
- case COUNTER_EXC_THROWN:
- sample->rawValue = mono_perfcounters->exceptions_thrown;
- return TRUE;
- }
- break;
case CATEGORY_ASPNET:
switch (id) {
case COUNTER_ASPNET_REQ_Q:
@@ -1009,25 +1014,6 @@ predef_writable_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounter
return TRUE;
}
break;
- case CATEGORY_JIT:
- switch (id) {
- case COUNTER_JIT_BYTES:
- sample->rawValue = mono_perfcounters->jit_bytes;
- return TRUE;
- case COUNTER_JIT_METHODS:
- sample->rawValue = mono_perfcounters->jit_methods;
- return TRUE;
- case COUNTER_JIT_TIME:
- sample->rawValue = mono_perfcounters->jit_time;
- return TRUE;
- case COUNTER_JIT_BYTES_PSEC:
- sample->rawValue = mono_perfcounters->jit_bytes;
- return TRUE;
- case COUNTER_JIT_FAILURES:
- sample->rawValue = mono_perfcounters->jit_failures;
- return TRUE;
- }
- break;
}
return FALSE;
}
@@ -1213,6 +1199,42 @@ custom_get_impl (SharedCategory *cat, MonoString* counter, MonoString* instance,
return custom_vtable (scounter, inst, (char*)inst + size + scounter->seq_num * sizeof (guint64));
}
+MonoBoolean
+mono_counter_get_sample (ImplVtable *vtable, MonoBoolean only_value, MonoCounterSample* sample)
+{
+ if (!only_value) {
+ fill_sample (sample);
+ sample->baseValue = 1;
+ }
+
+ MonoCounter* counter = vtable->arg;
+
+ sample->rawValue = mono_counters_raw_value(counter);
+
+ switch (counter->type & MONO_COUNTER_TYPE_MASK) {
+ case MONO_COUNTER_INT:
+ case MONO_COUNTER_UINT:
+ sample->counterType = NumberOfItems32;
+ case MONO_COUNTER_LONG:
+ case MONO_COUNTER_ULONG:
+ sample->counterType = NumberOfItems64;
+ case MONO_COUNTER_TIME_INTERVAL:
+ sample->counterType = ElapsedTime;
+ case MONO_COUNTER_DOUBLE:
+ sample->counterType = RawFraction;
+ default:
+ sample->counterType = NumberOfItems64;
+ }
+
+ return TRUE;
+}
+
+static void*
+mono_counter_get_impl (MonoCounter* counter, MonoString* instance, int* type)
+{
+ return create_vtable(counter, mono_counter_get_sample, NULL);
+}
+
static const CategoryDesc*
find_category (MonoString *category)
{
@@ -1224,6 +1246,20 @@ find_category (MonoString *category)
return NULL;
}
+static MonoCounter*
+find_mono_counter (MonoString* category, MonoString* counter)
+{
+ char* c_category = mono_string_to_utf8(category);
+ char* c_name = mono_string_to_utf8(counter);
+
+ MonoCounter* c_counter = mono_counters_find(c_category, c_name);
+
+ g_free(c_category);
+ g_free(c_name);
+
+ return c_counter;
+}
+
void*
mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString* instance,
MonoString* machine, int *type, MonoBoolean *custom)
@@ -1232,14 +1268,23 @@ mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString
/* no support for counters on other machines */
if (mono_string_compare_ascii (machine, "."))
return NULL;
+
cdesc = find_category (category);
if (!cdesc) {
+ MonoCounter* c_counter = find_mono_counter(category, counter);
+ if (c_counter) {
+ *custom = TRUE;
+ return mono_counter_get_impl (c_counter, instance, type);
+ }
+
SharedCategory *scat = find_custom_category (category);
- if (!scat)
- return NULL;
- *custom = TRUE;
- return custom_get_impl (scat, counter, instance, type);
- }
+ if (scat) {
+ *custom = TRUE;
+ return custom_get_impl (scat, counter, instance, type);
+ }
+
+ return NULL;
+ }
switch (cdesc->id) {
case CATEGORY_CPU:
return cpu_get_impl (counter, instance, type, custom);
@@ -1249,14 +1294,6 @@ mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString
return mono_mem_get_impl (counter, instance, type, custom);
case CATEGORY_NETWORK:
return network_get_impl (counter, instance, type, custom);
- case CATEGORY_JIT:
- case CATEGORY_EXC:
- case CATEGORY_GC:
- case CATEGORY_REMOTING:
- case CATEGORY_LOADING:
- case CATEGORY_THREAD:
- case CATEGORY_INTEROP:
- case CATEGORY_SECURITY:
case CATEGORY_ASPNET:
case CATEGORY_THREADPOOL:
return predef_writable_get_impl (cdesc->id, counter, instance, type, custom);
@@ -1490,13 +1527,14 @@ mono_perfcounter_category_names (MonoString *machine)
int i;
MonoArray *res;
MonoDomain *domain = mono_domain_get ();
- GSList *custom_categories, *tmp;
+ GSList *custom_categories, *counters_categories, *tmp;
/* no support for counters on other machines */
if (mono_string_compare_ascii (machine, "."))
return mono_array_new (domain, mono_get_string_class (), 0);
perfctr_lock ();
custom_categories = get_custom_categories ();
- res = mono_array_new (domain, mono_get_string_class (), NUM_CATEGORIES + g_slist_length (custom_categories));
+ counters_categories = get_counters_categories ();
+ res = mono_array_new (domain, mono_get_string_class (), NUM_CATEGORIES + g_slist_length (custom_categories) + g_slist_length (counters_categories));
for (i = 0; i < NUM_CATEGORIES; ++i) {
const CategoryDesc *cdesc = &predef_categories [i];
mono_array_setref (res, i, mono_string_new (domain, cdesc->name));
@@ -1506,8 +1544,14 @@ mono_perfcounter_category_names (MonoString *machine)
mono_array_setref (res, i, mono_string_new (domain, scat->name));
i++;
}
+ for (tmp = counters_categories; tmp; tmp = tmp->next) {
+ char *category = tmp->data;
+ mono_array_setref (res, i, mono_string_new (domain, category));
+ i++;
+ }
perfctr_unlock ();
g_slist_free (custom_categories);
+ g_slist_free (counters_categories);
return res;
}
@@ -1517,6 +1561,7 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
int i;
SharedCategory *scat;
const CategoryDesc *cdesc;
+ const char* ccat;
MonoArray *res;
MonoDomain *domain = mono_domain_get ();
/* no support for counters on other machines */
@@ -1531,6 +1576,18 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
}
return res;
}
+ ccat = mono_string_to_utf8(category);
+ for (i = 0; mono_counters_categories[i]; i++) {
+ if (strcmp(ccat, mono_counters_categories[i]) == 0) {
+ GSList *counters = mono_counters_in_category(ccat), *tmp;
+ res = mono_array_new(domain, mono_get_string_class(), g_slist_length (counters));
+ for (tmp = counters, i = 0; tmp; tmp = tmp->next, i++) {
+ mono_array_setref (res, i, mono_string_new (domain, tmp->data));
+ }
+ g_slist_free (counters);
+ return res;
+ }
+ }
perfctr_lock ();
scat = find_custom_category (category);
if (scat) {
diff --git a/mono/mini/driver.c b/mono/mini/driver.c
index d71c077..122455c 100644
--- a/mono/mini/driver.c
+++ b/mono/mini/driver.c
@@ -1382,9 +1382,7 @@ mono_jit_parse_options (int argc, char * argv[])
opt->break_on_exc = TRUE;
} else if (strcmp (argv [i], "--stats") == 0) {
- mono_counters_enable (-1);
- mono_stats.enabled = TRUE;
- mono_jit_stats.enabled = TRUE;
+ mono_counters_dump_on_cleanup = TRUE;
} else if (strcmp (argv [i], "--break") == 0) {
if (i+1 >= argc){
fprintf (stderr, "Missing method name in --break command line option\n");
@@ -1407,6 +1405,11 @@ mono_jit_parse_options (int argc, char * argv[])
}
}
+ // Always enable stats
+ mono_counters_enable (-1);
+ mono_stats.enabled = TRUE;
+ mono_jit_stats.enabled = TRUE;
+
if (trace_options != NULL) {
/*
* Need to call this before mini_init () so we can trace methods
@@ -1653,9 +1656,7 @@ mono_main (int argc, char* argv[])
} else if (strcmp (argv [i], "--print-vtable") == 0) {
mono_print_vtable = TRUE;
} else if (strcmp (argv [i], "--stats") == 0) {
- mono_counters_enable (-1);
- mono_stats.enabled = TRUE;
- mono_jit_stats.enabled = TRUE;
+ mono_counters_dump_on_cleanup = TRUE;
#ifndef DISABLE_AOT
} else if (strcmp (argv [i], "--aot") == 0) {
error_if_aot_unsupported ();
@@ -1824,6 +1825,11 @@ mono_main (int argc, char* argv[])
}
}
+ // Always enable counters
+ mono_counters_enable (-1);
+ mono_stats.enabled = TRUE;
+ mono_jit_stats.enabled = TRUE;
+
#ifdef __native_client_codegen__
if (g_getenv ("MONO_NACL_ALIGN_MASK_OFF"))
{
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index 616d696..13feb3f 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -6014,7 +6014,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
prof_method = cfg->method;
g_timer_stop (jit_timer);
- mono_jit_stats.jit_time += g_timer_elapsed (jit_timer, NULL);
+ mono_jit_stats.jit_time += g_timer_elapsed (jit_timer, NULL) * 1000;
g_timer_destroy (jit_timer);
switch (cfg->exception_type) {
@@ -7047,7 +7047,7 @@ register_jit_stats (void)
mono_counters_register ("Methods from AOT", MONO_COUNTER_JIT | MONO_COUNTER_WORD, &mono_jit_stats.methods_aot);
mono_counters_register ("Methods JITted using mono JIT", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_without_llvm);
mono_counters_register ("Methods JITted using LLVM", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_with_llvm);
- mono_counters_register ("Total time spent JITting (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_time);
+ mono_counters_register ("Total time spent JITting (msec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_time); // TODO : convert to MONO_COUNTER_TIME_INTERVAL
mono_counters_register ("Basic blocks", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.basic_blocks);
mono_counters_register ("Max basic blocks", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.max_basic_blocks);
mono_counters_register ("Allocated vars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocate_var);
@@ -7643,7 +7643,7 @@ MonoJitStats mono_jit_stats = {0};
static void
print_jit_stats (void)
{
- if (mono_jit_stats.enabled) {
+ if (mono_jit_stats.enabled && mono_counters_dump_on_cleanup) {
g_print ("Mono Jit statistics\n");
g_print ("Max code size ratio: %.2f (%s)\n", mono_jit_stats.max_code_size_ratio/100.0,
mono_jit_stats.max_ratio_method);
@@ -7761,7 +7761,8 @@ mini_cleanup (MonoDomain *domain)
mono_trace_cleanup ();
- mono_counters_dump (-1, stdout);
+ if (mono_counters_dump_on_cleanup)
+ mono_counters_dump (-1, stdout);
if (mono_inject_async_exc_method)
mono_method_desc_free (mono_inject_async_exc_method);
diff --git a/mono/utils/mono-counters.c b/mono/utils/mono-counters.c
index 7506289..97ba041 100644
--- a/mono/utils/mono-counters.c
+++ b/mono/utils/mono-counters.c
@@ -7,19 +7,21 @@
#include <glib.h>
#include "mono-counters.h"
-typedef struct _MonoCounter MonoCounter;
-
-struct _MonoCounter {
- MonoCounter *next;
- const char *name;
- void *addr;
- int type;
-};
-
static MonoCounter *counters = NULL;
static int valid_mask = 0;
static int set_mask = 0;
+MonoBoolean mono_counters_dump_on_cleanup = FALSE;
+
+const char* mono_counters_categories[] = {
+ "Mono JIT",
+ "Mono GC",
+ "Mono Metadata",
+ "Mono Generics",
+ "Mono Security",
+ NULL
+};
+
/**
* mono_counters_enable:
* @section_mask: a mask listing the sections that will be displayed
@@ -72,6 +74,57 @@ mono_counters_register (const char* name, int type, void *addr)
}
}
+int
+mono_counters_find_category (const char* category)
+{
+ int j, i;
+ for (j = 0, i = MONO_COUNTER_JIT; i < MONO_COUNTER_LAST_SECTION; j++, i <<= 1) {
+ if (strcmp(category, mono_counters_categories[j]) == 0) {
+ return i;
+ }
+ }
+ return 0x7FFFFFFF;
+}
+
+MonoCounter*
+mono_counters_find (const char* category, const char* name)
+{
+ if (!counters)
+ return NULL;
+
+ int type = mono_counters_find_category(category);
+
+ MonoCounter* item = counters;
+ do {
+ if (item->type & type && strcmp(name, item->name) == 0)
+ return item;
+ } while ((item = item->next));
+
+ return NULL;
+}
+
+GSList*
+mono_counters_in_category (const char* category)
+{
+ if (!counters) {
+ return NULL;
+ }
+
+ int type = mono_counters_find_category(category);
+ if (type == 0x7FFFFFFF)
+ return NULL;
+
+ GSList* list = NULL;
+ MonoCounter* item = counters;
+
+ do {
+ if (item->type & type)
+ list = g_slist_append(list, item->name);
+ } while ((item = item->next));
+
+ return list;
+}
+
typedef int (*IntFunc) (void);
typedef guint (*UIntFunc) (void);
typedef gint64 (*LongFunc) (void);
@@ -154,6 +207,50 @@ dump_counter (MonoCounter *counter, FILE *outfile) {
}
}
+gint64
+mono_counters_raw_value (MonoCounter *counter) {
+ switch (counter->type & MONO_COUNTER_TYPE_MASK) {
+ case MONO_COUNTER_INT:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((IntFunc)counter->addr) ();
+ else
+ return (gint64)*(int*)counter->addr;
+ case MONO_COUNTER_UINT:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((UIntFunc)counter->addr) ();
+ else
+ return (gint64)*(guint*)counter->addr;
+ case MONO_COUNTER_LONG:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return ((LongFunc)counter->addr) ();
+ else
+ return *(gint64*)counter->addr;
+ case MONO_COUNTER_ULONG:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((ULongFunc)counter->addr) ();
+ else
+ return (gint64)*(guint64*)counter->addr;
+ case MONO_COUNTER_TIME_INTERVAL:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((LongFunc)counter->addr) ();
+ else
+ return (gint64)*(gint64*)counter->addr;
+ case MONO_COUNTER_DOUBLE:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((DoubleFunc)counter->addr) ();
+ else
+ return (gint64)*(double*)counter->addr;
+ case MONO_COUNTER_WORD:
+ if (counter->type & MONO_COUNTER_CALLBACK)
+ return (gint64)((PtrFunc)counter->addr) ();
+ else
+ return (gint64)*(gssize*)counter->addr;
+ // case MONO_COUNTER_STRING:
+ default:
+ return (gint64)0;
+ }
+}
+
static const char
section_names [][10] = {
"JIT",
diff --git a/mono/utils/mono-counters.h b/mono/utils/mono-counters.h
index f18212f..c438164 100644
--- a/mono/utils/mono-counters.h
+++ b/mono/utils/mono-counters.h
@@ -3,6 +3,15 @@
#include <stdio.h>
#include <mono/utils/mono-publib.h>
+#include "eglib/src/glib.h"
+#include "mono/metadata/object.h"
+
+typedef struct _MonoCounter {
+ struct _MonoCounter *next;
+ const char *name;
+ void *addr;
+ int type;
+} MonoCounter;
enum {
MONO_COUNTER_INT, /* 32 bit int */
@@ -25,6 +34,10 @@ enum {
MONO_COUNTER_LAST_SECTION
};
+extern const char* mono_counters_categories[];
+
+extern MonoBoolean mono_counters_dump_on_cleanup;
+
MONO_API void mono_counters_enable (int section_mask);
/*
@@ -54,5 +67,12 @@ MONO_API int mono_runtime_resource_limit (int resource_type, uintptr_t s
MONO_API void mono_runtime_resource_set_callback (MonoResourceCallback callback);
MONO_API void mono_runtime_resource_check_limit (int resource_type, uintptr_t value);
+MONO_API gint64 mono_counters_raw_value (MonoCounter *counter);
+
+MONO_API int mono_counters_find_category (const char* category);
+MONO_API MonoCounter* mono_counters_find (const char* category, const char* name);
+
+MONO_API GSList* mono_counters_in_category (const char* category);
+
#endif /* __MONO_COUNTERS_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment