2005-03-04 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / metadata / mono-debug.c
index 7df70371cad895c336b33a28bdcd27ce7ab2bfc4..30265f398c72a037bd53c4c9338855edc857e866 100644 (file)
@@ -11,7 +11,7 @@
 
 #define SYMFILE_TABLE_CHUNK_SIZE       16
 #define DATA_TABLE_PTR_CHUNK_SIZE      256
-#define DATA_TABLE_CHUNK_SIZE          131072
+#define DATA_TABLE_CHUNK_SIZE          32768
 
 MonoSymbolTable *mono_symbol_table = NULL;
 MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
@@ -154,6 +154,9 @@ mono_debug_open_image (MonoImage *image)
 {
        MonoDebugHandle *handle;
 
+       if (mono_image_is_dynamic (image))
+               return NULL;
+
        handle = _mono_debug_get_image (image);
        if (handle != NULL)
                return handle;
@@ -166,9 +169,6 @@ mono_debug_open_image (MonoImage *image)
 
        g_hash_table_insert (mono_debug_handles, image, handle);
 
-       if (mono_image_is_dynamic (image))
-               return handle;
-
        handle->symfile = mono_debug_open_mono_symbol_file (handle, in_the_mono_debugger);
        if (in_the_mono_debugger)
                mono_debugger_add_symbol_file (handle);
@@ -183,7 +183,7 @@ mono_debug_close_image (MonoDebugHandle *handle)
                mono_debug_close_mono_symbol_file (handle->symfile);
        /* decrease the refcount added with mono_image_addref () */
        mono_image_close (handle->image);
-       /* FIXME: should also free handle->image_file? */
+       g_free (handle->image_file);
        g_free (handle->_priv);
        g_free (handle);
 }
@@ -201,56 +201,61 @@ mono_debug_add_assembly (MonoAssembly *assembly, gpointer user_data)
  * Returns the global offset which is to be used to reference this data item and
  * a pointer (in the `ptr' argument) which is to be used to write it.
  */
-static guint32
-allocate_data_item (MonoSymbolTable *table, MonoDebugDataItemType type, guint32 size, guint8 **ptr)
+static guint8 *
+allocate_data_item (MonoDebugDataItemType type, guint32 size)
 {
-       guint32 retval;
+       guint32 chunk_size;
        guint8 *data;
 
-       g_assert (size + 8 < DATA_TABLE_CHUNK_SIZE);
-       g_assert (ptr != NULL);
+       g_assert (mono_symbol_table);
+
+       if (size + 12 < DATA_TABLE_CHUNK_SIZE)
+               chunk_size = DATA_TABLE_CHUNK_SIZE;
+       else
+               chunk_size = size + 12;
 
        /* Initialize things if necessary. */
-       if (!table->current_data_table) {
-               table->current_data_table = g_malloc0 (DATA_TABLE_CHUNK_SIZE);
-               table->data_table_size = DATA_TABLE_CHUNK_SIZE;
-               table->data_table_chunk_size = DATA_TABLE_CHUNK_SIZE;
-               table->data_table_offset = 0;
+       if (!mono_symbol_table->current_data_table) {
+               mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
+               mono_symbol_table->current_data_table_size = chunk_size;
+               mono_symbol_table->current_data_table_offset = 4;
+
+               * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
        }
 
  again:
        /* First let's check whether there's still enough room in the current_data_table. */
-       if (table->data_table_offset + size + 8 < table->data_table_size) {
-               retval = table->data_table_offset;
-               table->data_table_offset += size + 8;
-               data = ((guint8 *) table->current_data_table) + retval - table->data_table_start;
+       if (mono_symbol_table->current_data_table_offset + size + 8 < mono_symbol_table->current_data_table_size) {
+               data = ((guint8 *) mono_symbol_table->current_data_table) + mono_symbol_table->current_data_table_offset;
+               mono_symbol_table->current_data_table_offset += size + 8;
+
                * ((guint32 *) data) = size;
                data += 4;
                * ((guint32 *) data) = type;
                data += 4;
-               *ptr = data;
-               return retval;
+               return data;
        }
 
        /* Add the current_data_table to the data_tables vector and ... */
-       if (!table->data_tables) {
+       if (!mono_symbol_table->data_tables) {
                guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE;
-               table->data_tables = g_malloc0 (tsize);
+               mono_symbol_table->data_tables = g_malloc0 (tsize);
        }
 
-       if (!((table->num_data_tables + 1) % DATA_TABLE_PTR_CHUNK_SIZE)) {
-               guint32 chunks = (table->num_data_tables + 1) / DATA_TABLE_PTR_CHUNK_SIZE;
+       if (!((mono_symbol_table->num_data_tables + 1) % DATA_TABLE_PTR_CHUNK_SIZE)) {
+               guint32 chunks = (mono_symbol_table->num_data_tables + 1) / DATA_TABLE_PTR_CHUNK_SIZE;
                guint32 tsize = sizeof (gpointer) * DATA_TABLE_PTR_CHUNK_SIZE * (chunks + 1);
 
-               table->data_tables = g_realloc (table->data_tables, tsize);
+               mono_symbol_table->data_tables = g_realloc (mono_symbol_table->data_tables, tsize);
        }
 
-       table->data_tables [table->num_data_tables++] = table->current_data_table;
+       mono_symbol_table->data_tables [mono_symbol_table->num_data_tables++] = mono_symbol_table->current_data_table;
 
        /* .... allocate a new current_data_table. */
-       table->current_data_table = g_malloc0 (DATA_TABLE_CHUNK_SIZE);
-       table->data_table_start = table->data_table_offset = table->data_table_size;
-       table->data_table_size += DATA_TABLE_CHUNK_SIZE;
+       mono_symbol_table->current_data_table = g_malloc0 (chunk_size);
+       mono_symbol_table->current_data_table_size = chunk_size;
+       mono_symbol_table->current_data_table_offset = 4;
+       * ((guint32 *) mono_symbol_table->current_data_table) = chunk_size;
 
        goto again;
 }
@@ -372,7 +377,7 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                return NULL;
        }
 
-       max_size = 24 + 8 * jit->num_line_numbers + 20 * (1 + jit->num_params + jit->num_locals);
+       max_size = 24 + 8 * jit->num_line_numbers + 16 * minfo->num_lexical_blocks + 20 * (1 + jit->num_params + jit->num_locals);
        if (max_size > BUFSIZ)
                ptr = oldptr = g_malloc (max_size);
        else
@@ -392,6 +397,38 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                last_native_offset = lne->native_offset;
        }
 
+       jit->num_lexical_blocks = minfo->num_lexical_blocks;
+       jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
+       for (i = 0; i < jit->num_lexical_blocks; i ++) {
+               MonoDebugLexicalBlockEntry *jit_lbe = &jit->lexical_blocks [i];
+               MonoSymbolFileLexicalBlockEntry *minfo_lbe = &minfo->lexical_blocks [i];
+
+               jit_lbe->il_start_offset = minfo_lbe->_start_offset;
+               jit_lbe->native_start_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_start_offset);
+
+               jit_lbe->il_end_offset = minfo_lbe->_end_offset;
+               jit_lbe->native_end_offset = _mono_debug_address_from_il_offset (jit, jit_lbe->il_end_offset);
+       }
+
+       last_il_offset = 0;
+       last_native_offset = 0;
+       write_leb128 (jit->num_lexical_blocks, ptr, &ptr);
+       for (i = 0; i < jit->num_lexical_blocks; i++) {
+               MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
+
+               write_sleb128 (lbe->il_start_offset - last_il_offset, ptr, &ptr);
+               write_sleb128 (lbe->native_start_offset - last_native_offset, ptr, &ptr);
+
+               last_il_offset = lbe->il_start_offset;
+               last_native_offset = lbe->native_start_offset;
+
+               write_sleb128 (lbe->il_end_offset - last_il_offset, ptr, &ptr);
+               write_sleb128 (lbe->native_end_offset - last_native_offset, ptr, &ptr);
+
+               last_il_offset = lbe->il_end_offset;
+               last_native_offset = lbe->native_end_offset;
+       }
+
        *ptr++ = jit->this_var ? 1 : 0;
        if (jit->this_var)
                write_variable (jit->this_var, ptr, &ptr);
@@ -416,7 +453,7 @@ mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDoma
                return NULL;
        }
 
-       allocate_data_item (mono_symbol_table, MONO_DEBUG_DATA_ITEM_METHOD, total_size, (guint8 **) &address);
+       address = (MonoDebugMethodAddress *) allocate_data_item (MONO_DEBUG_DATA_ITEM_METHOD, total_size);
 
        address->size = total_size;
        address->symfile_id = handle->index;
@@ -528,6 +565,26 @@ mono_debug_read_method (MonoDebugMethodAddress *address)
                lne->native_offset = native_offset;
        }
 
+       il_offset = 0;
+       native_offset = 0;
+       jit->num_lexical_blocks = read_leb128 (ptr, &ptr);
+       jit->lexical_blocks = g_new0 (MonoDebugLexicalBlockEntry, jit->num_lexical_blocks);
+       for (i = 0; i < jit->num_lexical_blocks; i ++) {
+               MonoDebugLexicalBlockEntry *lbe = &jit->lexical_blocks [i];
+
+               il_offset += read_sleb128 (ptr, &ptr);
+               native_offset += read_sleb128 (ptr, &ptr);
+
+               lbe->il_start_offset = il_offset;
+               lbe->native_start_offset = native_offset;
+
+               il_offset += read_sleb128 (ptr, &ptr);
+               native_offset += read_sleb128 (ptr, &ptr);
+
+               lbe->il_end_offset = il_offset;
+               lbe->native_end_offset = native_offset;
+       }
+
        if (*ptr++) {
                jit->this_var = g_new0 (MonoDebugVarInfo, 1);
                read_variable (jit->this_var, ptr, &ptr);
@@ -579,7 +636,7 @@ mono_debug_add_type (MonoClass *klass)
        MonoDebugClassEntry *entry;
        char buffer [BUFSIZ];
        guint8 *ptr, *oldptr;
-       guint32 token, i, size, total_size, max_size;
+       guint32 token, size, total_size, max_size;
        int base_offset = 0;
 
        handle = _mono_debug_get_image (klass->image);
@@ -597,7 +654,8 @@ mono_debug_add_type (MonoClass *klass)
                ptr = oldptr = buffer;
 
        token = get_token (klass);
-       g_assert (token);
+       if (!token)
+               return;
 
        if (klass->valuetype)
                base_offset = - (int)(sizeof (MonoObject));
@@ -605,7 +663,8 @@ mono_debug_add_type (MonoClass *klass)
        write_leb128 (token, ptr, &ptr);
        write_leb128 (klass->rank, ptr, &ptr);
        write_leb128 (klass->instance_size + base_offset, ptr, &ptr);
-       * ((gpointer *) ptr)++ = klass;
+       * ((gpointer *) ptr) = klass;
+       ptr += sizeof (gpointer);
 
        size = ptr - oldptr;
        g_assert (size < max_size);
@@ -616,10 +675,10 @@ mono_debug_add_type (MonoClass *klass)
                //        This should only happen for very big methods, for instance
                //        with more than 40.000 line numbers and more than 5.000
                //        local variables.
-               return NULL;
+               return;
        }
 
-       allocate_data_item (mono_symbol_table, MONO_DEBUG_DATA_ITEM_CLASS, total_size, (guint8 **) &entry);
+       entry = (MonoDebugClassEntry *) allocate_data_item (MONO_DEBUG_DATA_ITEM_CLASS, total_size);
 
        entry->size = total_size;
        entry->symfile_id = handle->index;