X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fdwarf2%2Fcooked-index.h;h=f3c26480a81e2507d0cd3927b8b90dd893170c3d;hb=2ab317fb8290ea96bdb446957d2e221634fd25c8;hp=0a38fc88e52bca428c19c4fae968a76ee5998063;hpb=51f5a4b8e9397ae9e93789cd7974fa62aeee6cd2;p=binutils-gdb.git diff --git a/gdb/dwarf2/cooked-index.h b/gdb/dwarf2/cooked-index.h index 0a38fc88e52..f3c26480a81 100644 --- a/gdb/dwarf2/cooked-index.h +++ b/gdb/dwarf2/cooked-index.h @@ -30,6 +30,10 @@ #include "gdbsupport/gdb_obstack.h" #include "addrmap.h" #include "gdbsupport/iterator-range.h" +#include "gdbsupport/thread-pool.h" +#include "dwarf2/mapped-index.h" +#include "dwarf2/tag.h" +#include "gdbsupport/range-chain.h" struct dwarf2_per_cu_data; @@ -105,11 +109,13 @@ struct cooked_index_entry : public allocate_on_obstack switch (kind) { case VARIABLES_DOMAIN: - return tag == DW_TAG_variable; + return (tag == DW_TAG_variable + || tag == DW_TAG_constant + || tag == DW_TAG_enumerator); case FUNCTIONS_DOMAIN: return tag == DW_TAG_subprogram; case TYPES_DOMAIN: - return tag == DW_TAG_typedef || tag == DW_TAG_structure_type; + return tag_is_type (tag); case MODULES_DOMAIN: return tag == DW_TAG_module; } @@ -155,6 +161,8 @@ private: void write_scope (struct obstack *storage, const char *sep) const; }; +class cooked_index_vector; + /* An index of interesting DIEs. This is "cooked", in contrast to a mapped .debug_names or .gdb_index, which are "raw". An entry in the index is of type cooked_index_entry. @@ -166,9 +174,7 @@ class cooked_index { public: cooked_index () = default; - explicit cooked_index (cooked_index &&other) = default; DISABLE_COPY_AND_ASSIGN (cooked_index); - cooked_index &operator= (cooked_index &&other) = default; /* Create a new cooked_index_entry and register it with this object. Entries are owned by this object. The new item is returned. */ @@ -178,56 +184,57 @@ public: const cooked_index_entry *parent_entry, dwarf2_per_cu_data *per_cu); - /* Return the entry that is believed to represent the program's - "main". This will return NULL if no such entry is available. */ - const cooked_index_entry *get_main () const - { - return m_main; - } - /* Install a new fixed addrmap from the given mutable addrmap. */ - void install_addrmap (addrmap *map) + void install_addrmap (addrmap_mutable *map) { gdb_assert (m_addrmap == nullptr); - m_addrmap = addrmap_create_fixed (map, &m_storage); - } - - /* Look up ADDR in the address map, and return either the - corresponding CU, or nullptr if the address could not be - found. */ - dwarf2_per_cu_data *lookup (CORE_ADDR addr) - { - return (dwarf2_per_cu_data *) addrmap_find (m_addrmap, addr); + m_addrmap = new (&m_storage) addrmap_fixed (&m_storage, map); } /* Finalize the index. This should be called a single time, when the index has been fully populated. It enters all the entries - into the internal hash table. */ + into the internal table. */ void finalize (); + /* Wait for this index's finalization to be complete. */ + void wait () + { + m_future.wait (); + } + + friend class cooked_index_vector; + /* A simple range over part of m_entries. */ typedef iterator_range::iterator> range; - /* Look up an entry by name. Returns a range of all matching - results. If COMPLETING is true, then a larger range, suitable - for completion, will be returned. */ - range find (gdb::string_view name, bool completing); - /* Return a range of all the entries. */ range all_entries () { + wait (); return { m_entries.begin (), m_entries.end () }; } + /* Look up an entry by name. Returns a range of all matching + results. If COMPLETING is true, then a larger range, suitable + for completion, will be returned. */ + range find (gdb::string_view name, bool completing); + private: - /* GNAT only emits mangled ("encoded") names in the DWARF, and does - not emit the module structure. However, we need this structure - to do lookups. This function recreates that structure for an - existing entry. It returns the base name (last element) of the - full decoded name. */ - gdb::unique_xmalloc_ptr handle_gnat_encoded_entry - (cooked_index_entry *entry, htab_t gnat_entries); + /* Return the entry that is believed to represent the program's + "main". This will return NULL if no such entry is available. */ + const cooked_index_entry *get_main () const + { + return m_main; + } + + /* Look up ADDR in the address map, and return either the + corresponding CU, or nullptr if the address could not be + found. */ + dwarf2_per_cu_data *lookup (CORE_ADDR addr) + { + return (dwarf2_per_cu_data *) m_addrmap->find (addr); + } /* Create a new cooked_index_entry and register it with this object. Entries are owned by this object. The new item is returned. */ @@ -243,6 +250,17 @@ private: per_cu); } + /* GNAT only emits mangled ("encoded") names in the DWARF, and does + not emit the module structure. However, we need this structure + to do lookups. This function recreates that structure for an + existing entry. It returns the base name (last element) of the + full decoded name. */ + gdb::unique_xmalloc_ptr handle_gnat_encoded_entry + (cooked_index_entry *entry, htab_t gnat_entries); + + /* A helper method that does the work of 'finalize'. */ + void do_finalize (); + /* Storage for the entries. */ auto_obstack m_storage; /* List of all entries. */ @@ -250,11 +268,95 @@ private: /* If we found "main" or an entry with 'is_main' set, store it here. */ cooked_index_entry *m_main = nullptr; - /* Storage for canonical names. */ - std::vector> m_names; /* The addrmap. This maps address ranges to dwarf2_per_cu_data objects. */ addrmap *m_addrmap = nullptr; + /* Storage for canonical names. */ + std::vector> m_names; + /* A future that tracks when the 'finalize' method is done. Note + that the 'get' method is never called on this future, only + 'wait'. */ + gdb::future m_future; +}; + +/* The main index of DIEs. The parallel DIE indexers create + cooked_index objects. Then, these are all handled to a + cooked_index_vector for storage and final indexing. The index is + made by iterating over the entries previously created. */ + +class cooked_index_vector : public dwarf_scanner_base +{ +public: + + /* A convenience typedef for the vector that is contained in this + object. */ + typedef std::vector> vec_type; + + explicit cooked_index_vector (vec_type &&vec); + DISABLE_COPY_AND_ASSIGN (cooked_index_vector); + + /* Wait until the finalization of the entire cooked_index_vector is + done. */ + void wait () + { + for (auto &item : m_vector) + item->wait (); + } + + ~cooked_index_vector () + { + /* The 'finalize' methods may be run in a different thread. If + this object is destroyed before these complete, then one will + end up writing to freed memory. Waiting for finalization to + complete avoids this problem; and the cost seems ignorable + because creating and immediately destroying the debug info is a + relatively rare thing to do. */ + wait (); + } + + /* A range over a vector of subranges. */ + typedef range_chain range; + + /* Look up an entry by name. Returns a range of all matching + results. If COMPLETING is true, then a larger range, suitable + for completion, will be returned. */ + range find (gdb::string_view name, bool completing); + + /* Return a range of all the entries. */ + range all_entries () + { + std::vector result_range; + result_range.reserve (m_vector.size ()); + for (auto &entry : m_vector) + result_range.push_back (entry->all_entries ()); + return range (std::move (result_range)); + } + + /* Look up ADDR in the address map, and return either the + corresponding CU, or nullptr if the address could not be + found. */ + dwarf2_per_cu_data *lookup (CORE_ADDR addr); + + /* Return a new vector of all the addrmaps used by all the indexes + held by this object. */ + std::vector get_addrmaps (); + + /* Return the entry that is believed to represent the program's + "main". This will return NULL if no such entry is available. */ + const cooked_index_entry *get_main () const; + + cooked_index_vector *index_for_writing () override + { + return this; + } + + quick_symbol_functions_up make_quick_functions () const override; + +private: + + /* The vector of cooked_index objects. This is stored because the + entries are stored on the obstacks in those objects. */ + vec_type m_vector; }; #endif /* GDB_DWARF2_COOKED_INDEX_H */