More C90 compatibility fixes
[mono.git] / mono / profiler / mono-profiler-iomap.c
index ef129b05efad049b41dc5d4336e2594119e75402..bc0dd2c1b65cc1ad70d71a62ae54332c18750afa 100644 (file)
@@ -5,6 +5,9 @@
  *   Marek Habersack <mhabersack@novell.com>
  *
  * Copyright (c) 2009 Novell, Inc (http://novell.com)
+ *
+ * Note: this profiler is completely unsafe wrt handling managed objects,
+ * don't use and don't copy code from here.
  */
 #include "config.h"
 
@@ -20,8 +23,9 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/profiler.h>
 #include <mono/metadata/loader.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
 
+#define LOCATION_INDENT "        "
 #define BACKTRACE_SIZE 64
 
 typedef struct _MonoStackBacktraceInfo 
@@ -94,13 +98,14 @@ static void mismatched_stats_foreach_func (gpointer key, gpointer value, gpointe
        StringLocation *location;
        MonoProfiler *prof = (MonoProfiler*)user_data;
        guint32 hash;
+       gboolean bannerShown = FALSE;
 
        hash = do_calc_string_hash (0, stats->requestedName);
        fprintf (stdout,
                 "    Count: %u\n"
-                "Requested: %s (hash: 0x%X)\n"
-                "   Actual: %s (hash: 0x%X)\n",
-                stats->count, stats->requestedName, hash, stats->actualName, do_calc_string_hash (0, stats->actualName));
+                "Requested: %s\n"
+                "   Actual: %s\n",
+                stats->count, stats->requestedName, stats->actualName);
 
        if (!prof->may_have_locations) {
                fprintf (stdout, "\n");
@@ -108,12 +113,17 @@ static void mismatched_stats_foreach_func (gpointer key, gpointer value, gpointe
        }
 
        location = g_hash_table_lookup (prof->string_locations_hash, &hash);
-       if (location)
-               fprintf (stdout, "Locations:\n");
-
        while (location) {
-               fprintf (stdout, "    %s", location->hint);
+               if (location->hint && strlen (location->hint) > 0) {
+                       if (!bannerShown) {
+                               fprintf (stdout, "Locations:\n");
+                               bannerShown = TRUE;
+                       }
+                       fprintf (stdout, "%s", location->hint);
+               }
                location = location->next;
+               if (location)
+                       fprintf (stdout, LOCATION_INDENT "--\n");
        }
 
        fprintf (stdout, "\n");
@@ -198,7 +208,7 @@ static inline void print_report (const gchar *format, ...)
 
 static inline void append_report (GString **report, const gchar *format, ...)
 {
-#if GLIB_CHECK_VERSION(2,14,0)
+#if defined (_EGLIB_MAJOR) || GLIB_CHECK_VERSION(2,14,0)
        va_list ap;
        if (!*report)
                *report = g_string_new ("");
@@ -218,7 +228,7 @@ static gboolean saved_strings_find_func (gpointer key, gpointer value, gpointer
        gchar *utf_str;
        guint32 hash;
 
-       if (!info || !saved || saved->string->length != info->len)
+       if (!info || !saved || mono_string_length (saved->string) != info->len)
                return FALSE;
 
        utf_str = mono_string_to_utf8 (saved->string);
@@ -349,10 +359,10 @@ static inline gchar *build_hint_from_stack (MonoDomain *domain, void **stack, gi
                        methodName = mono_method_full_name (method, TRUE);
 
                        if (location) {
-                               append_report (&trace, "        %s in %s:%u\n", methodName, location->source_file, location->row);
+                               append_report (&trace, LOCATION_INDENT "%s in %s:%u\n", methodName, location->source_file, location->row);
                                mono_debug_free_source_location (location);
                        } else
-                               append_report (&trace, "        %s\n", methodName);
+                               append_report (&trace, LOCATION_INDENT "%s\n", methodName);
                        g_free (methodName);
                }
 
@@ -367,10 +377,10 @@ static inline gchar *build_hint_from_stack (MonoDomain *domain, void **stack, gi
                methodName = mono_method_full_name (selectedMethod, TRUE);
 
                if (location) {
-                       hint = g_strdup_printf ("%s in %s:%u\n", methodName, location->source_file, location->row);
+                       hint = g_strdup_printf (LOCATION_INDENT "%s in %s:%u\n", methodName, location->source_file, location->row);
                        mono_debug_free_source_location (location);
                } else
-                       hint = g_strdup_printf ("%s\n", methodName);
+                       hint = g_strdup_printf (LOCATION_INDENT "%s\n", methodName);
                g_free (methodName);
        }
 
@@ -439,25 +449,19 @@ static void mono_portability_remember_string (MonoProfiler *prof, MonoDomain *do
 {
        SavedString *head, *entry;
 
-       /* fprintf (stdout, "%s (%p, %p, %p)\n", __func__, prof, str, klass); */
-       if (!str || !domain || !runtime_initialized) {
-               /* fprintf (stdout, "\truntime not initialized or str null\n"); */
-               /* fflush (stdout); */
+       if (!str || !domain || !runtime_initialized)
                return;
-       }
 
        entry = (SavedString*)g_malloc0 (sizeof (SavedString));
        entry->string = str;
        entry->domain = domain;
        entry->stack_entries = mono_stack_backtrace (prof, domain, entry->stack, BACKTRACE_SIZE);
-       /* fprintf (stdout, "\tstack_entries == %u\n", entry->stack_entries); */
-       /* fflush (stdout); */
        if (entry->stack_entries == 0) {
                g_free (entry);
                return;
        }
-       
-       //mono_mutex_lock (&mismatched_files_section);
+
+       mono_mutex_lock (&mismatched_files_section);
        head = (SavedString*)g_hash_table_lookup (prof->saved_strings_hash, (gpointer)str);
        if (head) {
                while (head->next)
@@ -465,7 +469,16 @@ static void mono_portability_remember_string (MonoProfiler *prof, MonoDomain *do
                head->next = entry;
        } else
                g_hash_table_insert (prof->saved_strings_hash, (gpointer)str, (gpointer)entry);
-       //mono_mutex_unlock (&mismatched_files_section);
+       mono_mutex_unlock (&mismatched_files_section);
+}
+
+static MonoClass *string_class = NULL;
+
+static void mono_portability_remember_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass)
+{
+       if (klass != string_class)
+               return;
+       mono_portability_remember_string (prof, mono_object_get_domain (obj), (MonoString*)obj);
 }
 
 static void mono_portability_iomap_event (MonoProfiler *prof, const char *report, const char *pathname, const char *new_pathname)
@@ -506,6 +519,7 @@ static void mono_portability_iomap_event (MonoProfiler *prof, const char *report
 static void runtime_initialized_cb (MonoProfiler *prof)
 {
        runtime_initialized = TRUE;
+       string_class = mono_get_string_class ();
 }
 
 static void profiler_shutdown (MonoProfiler *prof)
@@ -518,7 +532,7 @@ void mono_profiler_startup (const char *desc)
 {
        MonoProfiler *prof = g_new0 (MonoProfiler, 1);
 
-       mono_mutex_init (&mismatched_files_section, NULL);
+       mono_mutex_init (&mismatched_files_section);
        prof->mismatched_files_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
        prof->saved_strings_hash = g_hash_table_new (NULL, NULL);
        prof->string_locations_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
@@ -526,7 +540,7 @@ void mono_profiler_startup (const char *desc)
        mono_profiler_install (prof, profiler_shutdown);
        mono_profiler_install_runtime_initialized (runtime_initialized_cb);
        mono_profiler_install_iomap (mono_portability_iomap_event);
-       mono_profiler_install_string_allocation (mono_portability_remember_string);
+       mono_profiler_install_allocation (mono_portability_remember_alloc);
 
-       mono_profiler_set_events (MONO_PROFILE_STRING_ALLOC | MONO_PROFILE_IOMAP_EVENTS);
+       mono_profiler_set_events (MONO_PROFILE_ALLOCATIONS | MONO_PROFILE_IOMAP_EVENTS);
 }