This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [7/10] keep track of dependencies
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: Tom Tromey <tromey at redhat dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Thu, 26 Apr 2012 22:27:43 +0200
- Subject: Re: [7/10] keep track of dependencies
- References: <87zk9zabho.fsf@fleche.redhat.com>
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