Merge pull request #811 from criteo/16334-ConcurrentBag
[mono.git] / mono / metadata / mono-debug.c
index 1894c1199319b47aa1648158b0477d777ac65f4b..6eff0ecbda320d6a165b4be0582e800fa2fdc057 100644 (file)
@@ -6,6 +6,7 @@
  *
  * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
  * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
  */
 
 #include <config.h>
 #include <mono/metadata/mono-debug.h>
 #include <mono/metadata/mono-debug-debugger.h>
 #include <mono/metadata/mono-endian.h>
+#include <mono/metadata/gc-internal.h>
 #include <string.h>
 
-#define DATA_TABLE_CHUNK_SIZE          16384
+#define DATA_TABLE_CHUNK_SIZE          (16384-sizeof (MonoDebugDataChunk))
 
 #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
 
@@ -122,6 +124,8 @@ static void                 mono_debug_add_assembly    (MonoAssembly *assembly,
                                                        gpointer user_data);
 static void                 mono_debug_add_type        (MonoClass *klass);
 
+static MonoDebugHandle     *open_symfile_from_bundle   (MonoImage *image);
+
 void _mono_debug_init_corlib (MonoDomain *domain);
 
 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
@@ -159,9 +163,9 @@ free_header_data (gpointer key, gpointer value, gpointer user_data)
 
        if (header->wrapper_data) {
                g_free ((gpointer)header->wrapper_data->method_name);
-               g_slist_free (header->address_list);
                g_free (header->wrapper_data);
        }
+       g_slist_free (header->address_list);
 }
 
 static void
@@ -194,7 +198,10 @@ lookup_data_table (MonoDomain *domain)
        MonoDebugDataTable *table;
 
        table = g_hash_table_lookup (data_table_hash, domain);
-       g_assert (table);
+       if (!table) {
+               g_error ("lookup_data_table () failed for %p\n", domain);
+               g_assert (table);
+       }
        return table;
 }
 
@@ -275,6 +282,9 @@ _mono_debug_init_corlib (MonoDomain *domain)
 void
 mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents, int size)
 {
+       if (!mono_debug_initialized)
+               return;
+
        mono_debug_open_image (image, raw_contents, size);
 }
 
@@ -428,8 +438,14 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
 static void
 mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
 {
+       MonoDebugHandle *handle;
+       MonoImage *image;
+
        mono_debugger_lock ();
-       mono_debug_open_image (mono_assembly_get_image (assembly), NULL, 0);
+       image = mono_assembly_get_image (assembly);
+       handle = open_symfile_from_bundle (image);
+       if (!handle)
+               mono_debug_open_image (image, NULL, 0);
        mono_debugger_unlock ();
 }
 
@@ -636,12 +652,22 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
        for (i = 0; i < jit->num_locals; i++)
                write_variable (&jit->locals [i], ptr, &ptr);
 
+       *ptr++ = jit->gsharedvt_info_var ? 1 : 0;
+       if (jit->gsharedvt_info_var) {
+               write_variable (jit->gsharedvt_info_var, ptr, &ptr);
+               write_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+       }
+
        size = ptr - oldptr;
        g_assert (size < max_size);
        total_size = size + sizeof (MonoDebugMethodAddress);
 
-       address = (MonoDebugMethodAddress *) allocate_data_item (
-               table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);
+       if (method->dynamic) {
+               address = g_malloc0 (total_size);
+       } else {
+               address = (MonoDebugMethodAddress *) allocate_data_item (
+                                 table, MONO_DEBUG_DATA_ITEM_METHOD, total_size);
+       }
 
        address->header.size = total_size;
        address->header.symfile_id = handle ? handle->index : 0;
@@ -679,12 +705,49 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
 
        g_hash_table_insert (table->method_address_hash, method, address);
 
-       write_data_item (table, (guint8 *) address);
+       if (!method->dynamic)
+               write_data_item (table, (guint8 *) address);
 
        mono_debugger_unlock ();
        return address;
 }
 
+void
+mono_debug_remove_method (MonoMethod *method, MonoDomain *domain)
+{
+       MonoMethod *declaring;
+       MonoDebugDataTable *table;
+       MonoDebugMethodHeader *header;
+       MonoDebugMethodAddress *address;
+
+       if (!mono_debug_initialized)
+               return;
+
+       g_assert (method->dynamic);
+
+       mono_debugger_lock ();
+
+       table = lookup_data_table (domain);
+
+       declaring = method->is_inflated ? ((MonoMethodInflated *) method)->declaring : method;
+       g_hash_table_remove (table->method_hash, declaring);
+
+       address = g_hash_table_lookup (table->method_address_hash, method);
+       if (address) {
+               header = &address->header;
+
+               if (header->wrapper_data) {
+                       g_free ((char*)header->wrapper_data->method_name);
+                       g_free (header->wrapper_data);
+               }
+               g_free (address);
+       }
+
+       g_hash_table_remove (table->method_address_hash, method);
+
+       mono_debugger_unlock ();
+}
+
 void
 mono_debug_add_delegate_trampoline (gpointer code, int size)
 {
@@ -770,6 +833,8 @@ mono_debug_free_method_jit_info (MonoDebugMethodJitInfo *jit)
        g_free (jit->this_var);
        g_free (jit->params);
        g_free (jit->locals);
+       g_free (jit->gsharedvt_info_var);
+       g_free (jit->gsharedvt_locals_var);
        g_free (jit);
 }
 
@@ -814,6 +879,13 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
        for (i = 0; i < jit->num_locals; i++)
                read_variable (&jit->locals [i], ptr, &ptr);
 
+       if (*ptr++) {
+               jit->gsharedvt_info_var = g_new0 (MonoDebugVarInfo, 1);
+               jit->gsharedvt_locals_var = g_new0 (MonoDebugVarInfo, 1);
+               read_variable (jit->gsharedvt_info_var, ptr, &ptr);
+               read_variable (jit->gsharedvt_locals_var, ptr, &ptr);
+       }
+
        return jit;
 }
 
@@ -1187,3 +1259,45 @@ mono_is_debugger_attached (void)
        return is_attached;
 }
 
+/*
+ * Bundles
+ */
+
+typedef struct _BundledSymfile BundledSymfile;
+
+struct _BundledSymfile {
+       BundledSymfile *next;
+       const char *aname;
+       const mono_byte *raw_contents;
+       int size;
+};
+
+static BundledSymfile *bundled_symfiles = NULL;
+
+void
+mono_register_symfile_for_assembly (const char *assembly_name, const mono_byte *raw_contents, int size)
+{
+       BundledSymfile *bsymfile;
+
+       bsymfile = g_new0 (BundledSymfile, 1);
+       bsymfile->aname = assembly_name;
+       bsymfile->raw_contents = raw_contents;
+       bsymfile->size = size;
+       bsymfile->next = bundled_symfiles;
+       bundled_symfiles = bsymfile;
+}
+
+static MonoDebugHandle *
+open_symfile_from_bundle (MonoImage *image)
+{
+       BundledSymfile *bsymfile;
+
+       for (bsymfile = bundled_symfiles; bsymfile; bsymfile = bsymfile->next) {
+               if (strcmp (bsymfile->aname, image->module_name))
+                       continue;
+
+               return mono_debug_open_image (image, bsymfile->raw_contents, bsymfile->size);
+       }
+
+       return NULL;
+}