-
-
Save luhenry/9477349 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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