From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5925 invoked by alias); 11 Sep 2008 21:53:05 -0000 Received: (qmail 5915 invoked by uid 22791); 11 Sep 2008 21:53:04 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 11 Sep 2008 21:52:29 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 6FB692A96C9 for ; Thu, 11 Sep 2008 17:52:27 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id wyvkoiGs6IzK for ; Thu, 11 Sep 2008 17:52:27 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id E26C22A96C0 for ; Thu, 11 Sep 2008 17:52:26 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 9759DE7ACF; Thu, 11 Sep 2008 23:52:24 +0200 (CEST) Date: Thu, 11 Sep 2008 21:53:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: Re: [RFA/commit/dwarf] Create partial symbols for nested subprograms Message-ID: <20080911215224.GT12222@adacore.com> References: <20080910201959.GC10133@adacore.com> <20080910203437.GA26162@caradoc.them.org> <20080911175422.GS12222@adacore.com> <20080911183730.GA17809@caradoc.them.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="9Iq5ULCa7nGtWwZS" Content-Disposition: inline In-Reply-To: <20080911183730.GA17809@caradoc.them.org> User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-09/txt/msg00243.txt.bz2 --9Iq5ULCa7nGtWwZS Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1985 > I usually use 'gdb -batch foo.exe' to time reading partial symbols, > and 'gdb -readnow -batch foo.exe' to time full symbols (only partial > symbols are at issue here). And use the "time" command to measure the time elapsed? Somehow, I got reported user times and total times that fluctuated a little more than when I used the --statistics. > Your users must be more patient than mine or Tom's :-) I consider > startup time to be pretty important, and I've been working on bringing > it down... Tom's been working on an even more drastic version. They must be :). I wish I had time to try to make this time shorter, but the truth is we some other areas where I think improving performance is more critical. For instance, we could still do better with symbol lookups, but we are limited by the fact that we do our lookups by linkage name. We need to change that, but the initial reason for doing it that way is that because we had customers whose program was so big that we exceeded the maximum amount of memory we could allocate. I have some ideas on how to fix this and hopefully bring Ada back closer to what C++ does, but that'll have to wait for a moment when things are less hectic for me. > Does it work / help to do the check here too: > > > && (load_all > > || last_die->tag == DW_TAG_namespace > > || last_die->tag == DW_TAG_enumeration_type > > + || last_die->tag == DW_TAG_subprogram > > + || last_die->tag == DW_TAG_lexical_block > > || (cu->language != language_c > > && (last_die->tag == DW_TAG_class_type > > || last_die->tag == DW_TAG_interface_type Sure! Is that what you had in mind? 2008-09-11 Joel Brobecker * dwarf2read.c (add_partial_subprogram): New procedure. (scan_partial_symbols): Use it. (load_partial_dies): Read in children of subprogram and lexical blocks for Ada compilation units. Tested on x86-linux, no regression. -- Joel --9Iq5ULCa7nGtWwZS Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="nested.diff" Content-length: 4414 diff -r d71d6b13aae1 -r 23f6a0ad1bee gdb/dwarf2read.c --- a/gdb/dwarf2read.c Wed Sep 10 12:23:56 2008 -0700 +++ b/gdb/dwarf2read.c Thu Sep 11 14:41:11 2008 -0700 @@ -766,6 +766,10 @@ static void add_partial_namespace (struc static void add_partial_enumeration (struct partial_die_info *enum_pdi, struct dwarf2_cu *cu); + +static void add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu); static gdb_byte *locate_pdi_sibling (struct partial_die_info *orig_pdi, gdb_byte *info_ptr, @@ -1783,21 +1787,7 @@ scan_partial_symbols (struct partial_die switch (pdi->tag) { case DW_TAG_subprogram: - if (pdi->has_pc_info) - { - if (pdi->lowpc < *lowpc) - { - *lowpc = pdi->lowpc; - } - if (pdi->highpc > *highpc) - { - *highpc = pdi->highpc; - } - if (!pdi->is_declaration) - { - add_partial_symbol (pdi, cu); - } - } + add_partial_subprogram (pdi, lowpc, highpc, cu); break; case DW_TAG_variable: case DW_TAG_typedef: @@ -2145,6 +2135,51 @@ add_partial_namespace (struct partial_di if (pdi->has_children) scan_partial_symbols (pdi->die_child, lowpc, highpc, cu); +} + +/* Read a partial die corresponding to a subprogram and create a partial + symbol for that subprogram. When the CU language allows it, this + routine also defines a partial symbol for each nested subprogram + that this subprogram contains. + + DIE my also be a lexical block, in which case we simply search + recursively for suprograms defined inside that lexical block. + Again, this is only performed when the CU language allows this + type of definitions. */ + +static void +add_partial_subprogram (struct partial_die_info *pdi, + CORE_ADDR *lowpc, CORE_ADDR *highpc, + struct dwarf2_cu *cu) +{ + if (pdi->tag == DW_TAG_subprogram) + { + if (pdi->has_pc_info) + { + if (pdi->lowpc < *lowpc) + *lowpc = pdi->lowpc; + if (pdi->highpc > *highpc) + *highpc = pdi->highpc; + if (!pdi->is_declaration) + add_partial_symbol (pdi, cu); + } + } + + if (! pdi->has_children) + return; + + if (cu->language == language_ada) + { + pdi = pdi->die_child; + while (pdi != NULL) + { + fixup_partial_die (pdi, cu); + if (pdi->tag == DW_TAG_subprogram + || pdi->tag == DW_TAG_lexical_block) + add_partial_subprogram (pdi, lowpc, highpc, cu); + pdi = pdi->die_sibling; + } + } } /* See if we can figure out if the class lives in a namespace. We do @@ -5567,6 +5602,7 @@ load_partial_dies (bfd *abfd, gdb_byte * && !is_type_tag_for_partial (abbrev->tag) && abbrev->tag != DW_TAG_enumerator && abbrev->tag != DW_TAG_subprogram + && abbrev->tag != DW_TAG_lexical_block && abbrev->tag != DW_TAG_variable && abbrev->tag != DW_TAG_namespace && abbrev->tag != DW_TAG_member) @@ -5689,9 +5725,14 @@ load_partial_dies (bfd *abfd, gdb_byte * sizeof (struct partial_die_info)); /* For some DIEs we want to follow their children (if any). For C - we have no reason to follow the children of structures; for other + we have no reason to follow the children of structures; for other languages we have to, both so that we can get at method physnames - to infer fully qualified class names, and for DW_AT_specification. */ + to infer fully qualified class names, and for DW_AT_specification. + + For Ada, we need to scan the children of subprograms and lexical + blocks as well because Ada allows the definition of nested + entities that could be interesting for the debugger, such as + nested subprograms for instance. */ if (last_die->has_children && (load_all || last_die->tag == DW_TAG_namespace @@ -5700,7 +5741,10 @@ load_partial_dies (bfd *abfd, gdb_byte * && (last_die->tag == DW_TAG_class_type || last_die->tag == DW_TAG_interface_type || last_die->tag == DW_TAG_structure_type - || last_die->tag == DW_TAG_union_type)))) + || last_die->tag == DW_TAG_union_type)) + || (cu->language == language_ada + && (last_die->tag == DW_TAG_subprogram + || last_die->tag == DW_TAG_lexical_block)))) { nesting_level++; parent_die = last_die; --9Iq5ULCa7nGtWwZS--