From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29284 invoked by alias); 26 Apr 2012 20:28:18 -0000 Received: (qmail 29276 invoked by uid 22791); 26 Apr 2012 20:28:17 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,SPF_HELO_PASS,TW_BJ,TW_CP,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 26 Apr 2012 20:27:51 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q3QKRp5E021637 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 26 Apr 2012 16:27:51 -0400 Received: from host2.jankratochvil.net (ovpn-116-17.ams2.redhat.com [10.36.116.17]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q3QKRiMc011041 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Thu, 26 Apr 2012 16:27:46 -0400 Date: Thu, 26 Apr 2012 20:33:00 -0000 From: Jan Kratochvil To: Tom Tromey Cc: gdb-patches@sourceware.org Subject: Re: [7/10] keep track of dependencies Message-ID: <20120426202743.GA23244@host2.jankratochvil.net> References: <87zk9zabho.fsf@fleche.redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <87zk9zabho.fsf@fleche.redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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: 2012-04/txt/msg00963.txt.bz2 On Wed, 25 Apr 2012 20:54:11 +0200, Tom Tromey wrote: > @@ -445,6 +451,9 @@ struct dwarf2_per_cu_data > /* Data needed by the "quick" functions. */ > struct dwarf2_per_cu_quick_data *quick; > } v; > + > + /* The CUs we import using DW_TAG_imported_unit. */ Maybe to describe also its lifetime / usage. /* Once it is filled in by scan_partial_symbols and freed by process_psymtab_comp_unit to compute partial_symtab->dependencies, if psymtabs are in use. It is also filled in by process_die and freed by compute_symtab_includes to compute symtab->includes. */ > + VEC (dwarf2_per_cu_ptr) *imported_symtabs; > }; > > /* Entry in the signatured_types hash table. */ [...] > +/* Add a user to the list of psymtab users of INCLUDED. */ > + > +static void > +add_partial_user (htab_t user_hash, > + struct partial_symtab *included, > + struct partial_symtab *using_psymtab) > +{ > + void **slot; > + struct partial_users *user, tem; I think the variable name 'user' is confusing here - being exactly the opposite. USER (matching INCLUDED) is being used by USING_PSYMTAB here. I hope I did not mess the wording. > + > + tem.pst = included; > + slot = htab_find_slot (user_hash, &tem, INSERT); > + if (*slot == NULL) > + { > + user = XNEW (struct partial_users); > + user->pst = included; > + user->users = NULL; > + *slot = user; > + } > + else > + user = *slot; > + VEC_safe_push (partial_symtab_p, user->users, using_psymtab); > +} > + > +/* Compute the 'users' field for each psymtab in OBJFILE. */ > + > +static void > +set_partial_users (struct objfile *objfile) > +{ > + htab_t user_hash; > + int i; > + > + user_hash = htab_create_alloc (1, hash_partial_users, eq_partial_users, > + del_partial_users, xcalloc, xfree); > + > + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) > + { > + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); > + struct partial_symtab *pst = per_cu->v.psymtab; > + int j; > + > + for (j = 0; j < pst->number_of_dependencies; ++j) > + add_partial_user (user_hash, pst->dependencies[j], pst); > + } > + > + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) > + { > + struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); > + struct partial_symtab *pst = per_cu->v.psymtab; > + struct partial_users *user, tem; > + > + tem.pst = pst; > + user = htab_find (user_hash, &tem); > + if (user != NULL) > + { > + int len = VEC_length (partial_symtab_p, user->users); > + > + gdb_assert (len > 0); > + pst->users = obstack_alloc (&objfile->objfile_obstack, > + (len + 1) > + * sizeof (struct partial_symtab *)); I think here should be one more parentheses according to GCS. > + memcpy (pst->users, > + VEC_address (partial_symtab_p, user->users), > + len * sizeof (struct partial_symtab *)); > + pst->users[len] = NULL; > + } > + } > + > + htab_delete (user_hash); > +} > + > /* Build the partial symbol table by doing a quick pass through the > .debug_info and .debug_abbrev sections. */ > [...] > +/* A helper function for computing the list of all symbol tables > + included by PER_CU. */ > + > +static void > +recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result, > + htab_t all_children, > + struct dwarf2_per_cu_data *per_cu) > +{ > + void **slot; > + int ix; > + struct dwarf2_per_cu_data *iter; > + > + slot = htab_find_slot (all_children, per_cu, INSERT); > + if (*slot != NULL) > + { > + /* This inclusion and its children have been processed. */ > + return; > + } > + > + *slot = per_cu; > + /* Only add a CU if it has a symbol table. */ > + if (get_symtab (per_cu) != NULL) > + VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu); > + > + for (ix = 0; > + VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter); > + ++ix) > + recursively_compute_inclusions (result, all_children, iter); > +} > + > +/* Compute the symtab 'includes' fields for the symtab related to > + PER_CU. */ > + > +static void > +compute_symtab_includes (struct dwarf2_per_cu_data *per_cu) > +{ > + if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs)) > + { > + int ix, len; > + struct dwarf2_per_cu_data *iter; > + VEC (dwarf2_per_cu_ptr) *result_children = NULL; > + htab_t all_children; > + struct symtab *symtab = get_symtab (per_cu); > + > + /* If we don't have a symtab, we can just skip this case. */ > + if (symtab == NULL) > + return; > + > + all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer, > + NULL, xcalloc, xfree); > + > + for (ix = 0; > + VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, > + ix, iter); > + ++ix) > + recursively_compute_inclusions (&result_children, all_children, iter); > + > + /* Now we have a transitive closure of all the included CUs, so > + we can convert it to a list of symtabs. */ > + len = VEC_length (dwarf2_per_cu_ptr, result_children); > + symtab->includes > + = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack, > + (len + 1) * sizeof (struct symtab *)); > + for (ix = 0; > + VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter); > + ++ix) Why is RESULT_CHILDREN used here at all? Would not it be sufficient to just call htab_traverse for ALL_CHILDREN? > + symtab->includes[ix] = get_symtab (iter); > + symtab->includes[len] = NULL; > + > + VEC_free (dwarf2_per_cu_ptr, result_children); > + htab_delete (all_children); > + } > +} [...] > @@ -5005,6 +5276,31 @@ process_die (struct die_info *die, struct dwarf2_cu *cu) > dwarf_tag_name (die->tag)); > read_import_statement (die, cu); > break; > + > + case DW_TAG_imported_unit: process_die only calls functions in general, it would be nice to put this block into a new function. > + { > + struct attribute *attr; > + > + attr = dwarf2_attr (die, DW_AT_import, cu); > + if (attr != NULL) > + { > + struct dwarf2_per_cu_data *per_cu; > + struct symtab *imported_symtab; > + sect_offset offset; > + > + offset = dwarf2_get_ref_die_offset (attr); > + per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile); > + > + /* Queue the unit, if needed. */ > + if (maybe_queue_comp_unit (cu, per_cu)) > + load_full_comp_unit (per_cu); > + > + VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs, > + per_cu); > + } > + } > + break; > + > default: > new_symbol (die, NULL, cu); > break; Thanks, Jan