diff options
author | Zoltan Varga <vargaz@gmail.com> | 2012-12-04 21:36:58 +0400 |
---|---|---|
committer | Zoltan Varga <vargaz@gmail.com> | 2012-12-04 21:37:18 +0400 |
commit | 804ff756b9dfd03b4c5e92916e2381172358241e (patch) | |
tree | 6e1d924b3cf9a1221f75aff920edc3d36d1ec890 | |
parent | c9d9d4d9190f899fe148008423cc6ee6c8cdc220 (diff) |
Optimize the emission of dwarf line number info by mostly ordering the methods by their line numbers. dlsymutil becomes very slow otherwise.
-rw-r--r-- | mono/mini/dwarfwriter.c | 102 | ||||
-rw-r--r-- | mono/mini/method-to-ir.c | 1 |
2 files changed, 57 insertions, 46 deletions
diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index 60bbfd4e93b..2f216dda226 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -52,6 +52,7 @@ struct _MonoDwarfWriter const char *temp_prefix; gboolean emit_line, appending, collect_line_info; GSList *line_info; + int cur_file_index; }; static void @@ -111,6 +112,7 @@ mono_dwarf_writer_create (MonoImageWriter *writer, FILE *il_file, int il_file_st w->class_to_vtype_die = g_hash_table_new (NULL, NULL); w->class_to_pointer_die = g_hash_table_new (NULL, NULL); w->class_to_reference_die = g_hash_table_new (NULL, NULL); + w->cur_file_index = -1; return w; } @@ -763,14 +765,15 @@ emit_all_line_number_info (MonoDwarfWriter *w) int i; GHashTable *dir_to_index, *index_to_dir; GSList *l; + GSList *info_list; g_assert (w->collect_line_info); add_line_number_file_name (w, "<unknown>", 0, 0); /* Collect files */ - // FIXME: Revert list - for (l = w->line_info; l; l = l->next) { + info_list = g_slist_reverse (w->line_info); + for (l = info_list; l; l = l->next) { MethodLineNumberInfo *info = l->data; MonoDebugMethodInfo *minfo; char *source_file; @@ -877,11 +880,12 @@ emit_all_line_number_info (MonoDwarfWriter *w) emit_label (w, ".Ldebug_line_header_end"); /* Emit line number table */ - for (l = w->line_info; l; l = l->next) { + for (l = info_list; l; l = l->next) { MethodLineNumberInfo *info = l->data; emit_line_number_info (w, info->method, info->start_symbol, info->end_symbol, info->code, info->code_size, info->debug_info); } + g_slist_free (info_list); emit_byte (w, 0); emit_byte (w, 1); @@ -1597,6 +1601,7 @@ emit_advance_op (MonoDwarfWriter *w, int line_diff, int addr_diff) if (opcode != 0) { emit_byte (w, opcode); } else { + //printf ("large: %d %d %d\n", line_diff, addr_diff, max_special_addr_diff); emit_byte (w, DW_LNS_advance_line); emit_sleb128 (w, line_diff); emit_byte (w, DW_LNS_advance_pc); @@ -1630,7 +1635,7 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, MonoDebugMethodInfo *minfo; MonoDebugLineNumberEntry *ln_array; int *native_to_il_offset = NULL; - + if (!w->emit_line) { mono_metadata_free_mh (header); return; @@ -1674,6 +1679,8 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, prev_il_offset = -1; for (i = 0; i < code_size; ++i) { + int line_diff, addr_diff; + if (!minfo) continue; @@ -1700,57 +1707,60 @@ emit_line_number_info (MonoDwarfWriter *w, MonoMethod *method, prev_il_offset = il_offset; loc = mono_debug_symfile_lookup_location (minfo, il_offset); - if (loc && loc->source_file) { - int line_diff = (gint32)loc->row - (gint32)prev_line; - int addr_diff = i - prev_native_offset; - - if (first) { - emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA); - - emit_byte (w, 0); - emit_byte (w, sizeof (gpointer) + 1); - emit_byte (w, DW_LNE_set_address); - if (start_symbol) - emit_pointer_unaligned (w, start_symbol); - else - emit_pointer_value (w, code); + if (!(loc && loc->source_file)) + continue; - /* - * The prolog+initlocals region does not have a line number, this - * makes them belong to the first line of the method. - */ - emit_byte (w, DW_LNS_advance_line); - emit_sleb128 (w, (gint32)loc->row - (gint32)prev_line); - prev_line = loc->row; - } + line_diff = (gint32)loc->row - (gint32)prev_line; + addr_diff = i - prev_native_offset; - if (loc->row != prev_line) { - if (!prev_file_name || strcmp (loc->source_file, prev_file_name) != 0) { - /* Add an entry to the file table */ - /* FIXME: Avoid duplicates */ - if (w->collect_line_info) - file_index = get_line_number_file_name (w, loc->source_file) + 1; - else - file_index = emit_line_number_file_name (w, loc->source_file, 0, 0); - g_free (prev_file_name); - prev_file_name = g_strdup (loc->source_file); + if (first) { + emit_section_change (w, ".debug_line", LINE_SUBSECTION_DATA); + emit_byte (w, 0); + emit_byte (w, sizeof (gpointer) + 1); + emit_byte (w, DW_LNE_set_address); + if (start_symbol) + emit_pointer_unaligned (w, start_symbol); + else + emit_pointer_value (w, code); + + /* + * The prolog+initlocals region does not have a line number, this + * makes them belong to the first line of the method. + */ + emit_byte (w, DW_LNS_advance_line); + //printf ("FIRST: %d %d %d\n", prev_line, loc->row, il_offset); + emit_sleb128 (w, (gint32)loc->row - (gint32)prev_line); + prev_line = loc->row; + first = FALSE; + } + + if (loc->row != prev_line) { + if (!prev_file_name || strcmp (loc->source_file, prev_file_name) != 0) { + /* Add an entry to the file table */ + /* FIXME: Avoid duplicates */ + if (w->collect_line_info) + file_index = get_line_number_file_name (w, loc->source_file) + 1; + else + file_index = emit_line_number_file_name (w, loc->source_file, 0, 0); + g_free (prev_file_name); + prev_file_name = g_strdup (loc->source_file); + + if (w->cur_file_index != file_index) { emit_byte (w, DW_LNS_set_file); emit_uleb128 (w, file_index); emit_byte (w, DW_LNS_copy); - } - //printf ("X: %p(+0x%x) %d %s:%d(+%d)\n", code + i, addr_diff, loc->il_offset, loc->source_file, loc->row, line_diff); - - emit_advance_op (w, line_diff, addr_diff); - - prev_line = loc->row; - prev_native_offset = i; + w->cur_file_index = file_index; + } } + //printf ("X: %p(+0x%x) %d %s:%d(+%d)\n", code + i, addr_diff, loc->il_offset, loc->source_file, loc->row, line_diff); + emit_advance_op (w, line_diff, addr_diff); - first = FALSE; - - mono_debug_symfile_free_location (loc); + prev_line = loc->row; + prev_native_offset = i; } + + mono_debug_symfile_free_location (loc); } g_free (native_to_il_offset); diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 3ca8845118b..f8e641a2d27 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -3920,6 +3920,7 @@ mono_emit_load_got_addr (MonoCompile *cfg) return; MONO_INST_NEW (cfg, getaddr, OP_LOAD_GOTADDR); + getaddr->cil_code = cfg->header->code; getaddr->dreg = cfg->got_var->dreg; /* Add it to the start of the first bblock */ |