#include "mono/metadata/mono-debug.h"
#include "mono/metadata/class-internals.h"
#include "mono/metadata/domain-internals.h"
+#include "mono/metadata/gc-internal.h"
#include "mono/io-layer/io-layer.h"
#include <string.h>
#include <sys/time.h>
static MonoProfileFunc shutdown_callback;
+static MonoProfileGCFunc gc_event;
+static MonoProfileGCResizeFunc gc_heap_resize;
+
+#define mono_profiler_coverage_lock() EnterCriticalSection (&profiler_coverage_mutex)
+#define mono_profiler_coverage_unlock() LeaveCriticalSection (&profiler_coverage_mutex)
static CRITICAL_SECTION profiler_coverage_mutex;
/* this is directly accessible to other mono libs. */
}
void
-mono_profiler_thread_start (guint32 tid)
+mono_profiler_thread_start (gsize tid)
{
if ((mono_profiler_events & MONO_PROFILE_THREADS) && thread_start)
thread_start (current_profiler, tid);
}
void
-mono_profiler_thread_end (guint32 tid)
+mono_profiler_thread_end (gsize tid)
{
if ((mono_profiler_events & MONO_PROFILE_THREADS) && thread_end)
thread_end (current_profiler, tid);
shutdown_callback (current_profiler);
}
+void
+mono_profiler_gc_heap_resize (gint64 new_size)
+{
+ if ((mono_profiler_events & MONO_PROFILE_GC) && gc_heap_resize)
+ gc_heap_resize (current_profiler, new_size);
+}
+
+void
+mono_profiler_gc_event (MonoGCEvent event, int generation)
+{
+ if ((mono_profiler_events & MONO_PROFILE_GC) && gc_event)
+ gc_event (current_profiler, event, generation);
+}
+
+void
+mono_profiler_install_gc (MonoProfileGCFunc callback, MonoProfileGCResizeFunc heap_resize_callback)
+{
+ mono_gc_enable_events ();
+ gc_event = callback;
+ gc_heap_resize = heap_resize_callback;
+}
+
static GHashTable *coverage_hash = NULL;
MonoProfileCoverageInfo*
if (! (*coverage_filter_cb) (current_profiler, method))
return NULL;
- EnterCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_lock ();
if (!coverage_hash)
coverage_hash = g_hash_table_new (NULL, NULL);
res->entries = entries;
g_hash_table_insert (coverage_hash, method, res);
- LeaveCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_unlock ();
return res;
}
{
MonoProfileCoverageInfo* info;
- EnterCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_lock ();
if (!coverage_hash) {
- LeaveCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_unlock ();
return;
}
g_free (info);
g_hash_table_remove (coverage_hash, method);
}
- LeaveCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_unlock ();
}
void
MonoMethodHeader *header;
MonoProfileCoverageEntry entry;
- EnterCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_lock ();
info = g_hash_table_lookup (coverage_hash, method);
- LeaveCriticalSection (&profiler_coverage_mutex);
+ mono_profiler_coverage_unlock ();
if (!info)
return;
struct _AllocInfo {
AllocInfo *next;
MonoClass *klass;
- guint count;
- guint mem;
+ guint64 count;
+ guint64 mem;
};
struct _CallerInfo {
{
char *sig, *res;
- sig = mono_signature_get_desc (method->signature, FALSE);
- res = g_strdup_printf ("%s.%s::%s(%s)", method->klass->name_space, method->klass->name,
+ sig = mono_signature_get_desc (mono_method_signature (method), FALSE);
+ res = g_strdup_printf ("%s%s%s::%s(%s)", method->klass->name_space,
+ method->klass->name_space ? "." : "", method->klass->name,
method->name, sig);
g_free (sig);
return res;
m = method_get_name (p->method);
printf ("########################\n");
printf ("% 8.3f ", (double) (p->total * 1000));
- printf ("%7llu ", p->count);
+ printf ("%7llu ", (unsigned long long)p->count);
printf ("% 8.3f ", (double) (p->total * 1000)/(double)p->count);
printf (" %s\n", m);
/* callers */
output_callers (p);
}
- printf ("Total number of calls: %lld\n", total_calls);
+ printf ("Total number of calls: %lld\n", (long long)total_calls);
}
typedef struct {
MethodProfile *mp;
- guint count;
+ guint64 count;
} NewobjProfile;
static gint
compare_newobj_profile (NewobjProfile *profa, NewobjProfile *profb)
{
- return (gint)profb->count - (gint)profa->count;
+ if (profb->count == profa->count)
+ return 0;
+ else
+ return profb->count > profa->count ? 1 : -1;
}
static void
{
NewobjProfile *prof = g_new (NewobjProfile, 1);
AllocInfo *tmp;
- guint count = 0;
+ guint64 count = 0;
prof->mp = mprof;
/* we use the total amount of memory to sort */
}
}
+/* This isn't defined on older glib versions and on some platforms */
+#ifndef G_GUINT64_FORMAT
+#define G_GUINT64_FORMAT "ul"
+#endif
+
static void
output_newobj_profile (GList *proflist)
{
const char* isarray;
char buf [256];
char *m;
- guint total = 0;
+ guint64 total = 0;
GSList *sorted, *tmps;
g_print ("\nAllocation profiler\n");
continue;
mp = p->mp;
m = method_get_name (mp->method);
- g_print ("########################\n%8d KB %s\n", p->count / 1024, m);
+ g_print ("########################\n%8" G_GUINT64_FORMAT " KB %s\n", (p->count / 1024), m);
g_free (m);
sorted = sort_alloc_list (mp->alloc_info);
for (tmps = sorted; tmps; tmps = tmps->next) {
} else {
isarray = "";
}
- g_snprintf (buf, sizeof (buf), "%s.%s%s",
- klass->name_space, klass->name, isarray);
- g_print (" %8d KB %8d %-48s\n", ainfo->mem / 1024, ainfo->count, buf);
+ g_snprintf (buf, sizeof (buf), "%s%%s%s",
+ klass->name_space, klass->name_space ? "." : "", klass->name, isarray);
+ g_print (" %8" G_GUINT64_FORMAT " KB %8" G_GUINT64_FORMAT " %-48s\n", (ainfo->mem / 1024), ainfo->count, buf);
}
/* callers */
output_callers (mp);
}
- g_print ("Total memory allocated: %d KB\n", total / 1024);
+ g_print ("Total memory allocated: %" G_GUINT64_FORMAT " KB\n", total / 1024);
}
static void
char *mn;
gpointer ip;
GList *tmp, *sorted = NULL;
+ int pcount = ++ prof_counts;
- prof_counts ++;
+ prof_counts = MAX_PROF_SAMPLES;
for (i = 0; i < count; ++i) {
ip = prof_addresses [i];
ji = mono_jit_info_table_find (mono_domain_get (), ip);
if (c > 1)
g_free (mn);
}
- g_print ("prof counts: total/unmanaged: %d/%d\n", prof_counts, prof_ucounts);
+ g_print ("prof counts: total/unmanaged: %d/%d\n", pcount, prof_ucounts);
g_hash_table_foreach (prof_table, (GHFunc)prof_foreach, &sorted);
for (tmp = sorted; tmp; tmp = tmp->next) {
double perc;
g_list_free (profile);
g_free (prof_addresses);
+ prof_addresses = NULL;
g_hash_table_destroy (prof_table);
}
{
MonoProfiler *prof;
gchar **args, **ptr;
- MonoProfileFlags flags = MONO_PROFILE_JIT_COMPILATION;
+ MonoProfileFlags flags = 0;
MONO_TIMER_STARTUP;
if (!desc)
- desc = "alloc,time";
+ desc = "alloc,time,jit";
if (desc) {
/* Parse options */
if (strstr (desc, ":"))
desc = strstr (desc, ":") + 1;
else
- desc = "alloc,time";
+ desc = "alloc,time,jit";
args = g_strsplit (desc, ",", -1);
for (ptr = args; ptr && *ptr; ptr++) {
flags |= MONO_PROFILE_ALLOCATIONS;
else if (!strcmp (arg, "stat"))
flags |= MONO_PROFILE_STATISTICAL | MONO_PROFILE_APPDOMAIN_EVENTS;
+ else if (!strcmp (arg, "jit"))
+ flags |= MONO_PROFILE_JIT_COMPILATION;
else {
fprintf (stderr, "profiler : Unknown argument '%s'.\n", arg);
return;