diff options
author | Simon Marchi <simon.marchi@polymtl.ca> | 2024-11-04 13:27:55 -0500 |
---|---|---|
committer | Simon Marchi <simon.marchi@polymtl.ca> | 2024-11-25 22:07:04 -0500 |
commit | de2b4ab50de5bfea2a8ea861510e59a95811697f (patch) | |
tree | 7da344954d7e04fb9a6910f53ec498d097172a9d | |
parent | a5a6ba04802332630b73148efc92df6ddd69e4b7 (diff) | |
download | binutils-de2b4ab50de5bfea2a8ea861510e59a95811697f.zip binutils-de2b4ab50de5bfea2a8ea861510e59a95811697f.tar.gz binutils-de2b4ab50de5bfea2a8ea861510e59a95811697f.tar.bz2 |
Convert dwarf2_cu::call_site_htab to new hash table
Convert one use of htab_t, mapping (unrelocated) pc to call_site
objects, to `gdb::unordered_map<unrelocated_addr, call_site *>`.
Change-Id: I40a0903253a8589dbdcb75d52ad4d233931f6641
Approved-By: Tom Tromey <tom@tromey.com>
-rw-r--r-- | gdb/dwarf2/call-site.h | 65 | ||||
-rw-r--r-- | gdb/dwarf2/cu.h | 2 | ||||
-rw-r--r-- | gdb/dwarf2/read.c | 26 | ||||
-rw-r--r-- | gdb/symtab.c | 30 | ||||
-rw-r--r-- | gdb/symtab.h | 5 |
5 files changed, 65 insertions, 63 deletions
diff --git a/gdb/dwarf2/call-site.h b/gdb/dwarf2/call-site.h index 0a0c7e8..82426c7 100644 --- a/gdb/dwarf2/call-site.h +++ b/gdb/dwarf2/call-site.h @@ -25,6 +25,7 @@ #include "dwarf2/types.h" #include "../frame.h" #include "gdbsupport/function-view.h" +#include "gdbsupport/unordered_set.h" struct dwarf2_locexpr_baton; struct dwarf2_per_cu_data; @@ -168,33 +169,16 @@ struct call_site : per_cu (per_cu), per_objfile (per_objfile), m_unrelocated_pc (pc) {} - static int - eq (const call_site *a, const call_site *b) - { - return a->m_unrelocated_pc == b->m_unrelocated_pc; - } + /* Return the relocated (using the objfile from PER_OBJFILE) address of the + first instruction after this call. */ - static hashval_t - hash (const call_site *a) - { - return (hashval_t) a->m_unrelocated_pc; - } - - static int - eq (const void *a, const void *b) - { - return eq ((const call_site *)a, (const call_site *)b); - } - - static hashval_t - hash (const void *a) - { - return hash ((const call_site *)a); - } + CORE_ADDR pc () const; - /* Return the address of the first instruction after this call. */ + /* Return the unrelocated address of the first instruction after this + call. */ - CORE_ADDR pc () const; + unrelocated_addr unrelocated_pc () const noexcept + { return m_unrelocated_pc; } /* Call CALLBACK for each target address. CALLER_FRAME (for registers) can be NULL if it is not known. This function may @@ -241,4 +225,37 @@ public: struct call_site_parameter parameter[]; }; +/* Key hash type to store call_site objects in gdb::unordered_set, identified by + their unrelocated PC. */ + +struct call_site_hash_pc +{ + using is_transparent = void; + + std::size_t operator() (const call_site *site) const noexcept + { return (*this) (site->unrelocated_pc ()); } + + std::size_t operator() (unrelocated_addr pc) const noexcept + { return std::hash<unrelocated_addr> () (pc); } +}; + +/* Key equal type to store call_site objects in gdb::unordered_set, identified + by their unrelocated PC. */ + +struct call_site_eq_pc +{ + using is_transparent = void; + + bool operator() (const call_site *a, const call_site *b) const noexcept + { return (*this) (a->unrelocated_pc (), b); } + + bool operator() (unrelocated_addr pc, const call_site *site) const noexcept + { return pc == site->unrelocated_pc (); } +}; + +/* Set of call_site objects identified by their unrelocated PC. */ + +using call_site_htab_t + = gdb::unordered_set<call_site *, call_site_hash_pc, call_site_eq_pc>; + #endif /* CALL_SITE_H */ diff --git a/gdb/dwarf2/cu.h b/gdb/dwarf2/cu.h index 23b06dc..737d3ba 100644 --- a/gdb/dwarf2/cu.h +++ b/gdb/dwarf2/cu.h @@ -175,7 +175,7 @@ public: std::vector<delayed_method_info> method_list; /* To be copied to symtab->call_site_htab. */ - htab_up call_site_htab; + call_site_htab_t call_site_htab; /* Non-NULL if this CU came from a DWO file. There is an invariant here that is important to remember: diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index b20d3cd..4be122f 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -10289,7 +10289,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) struct objfile *objfile = per_objfile->objfile; struct gdbarch *gdbarch = objfile->arch (); struct attribute *attr; - void **slot; int nparams; struct die_info *child_die; @@ -10309,21 +10308,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) } unrelocated_addr pc = attr->as_address (); - if (cu->call_site_htab == nullptr) - cu->call_site_htab.reset (htab_create_alloc (16, call_site::hash, - call_site::eq, nullptr, - xcalloc, xfree)); - struct call_site call_site_local (pc, nullptr, nullptr); - slot = htab_find_slot (cu->call_site_htab.get (), &call_site_local, INSERT); - if (*slot != NULL) - { - complaint (_("Duplicate PC %s for DW_TAG_call_site " - "DIE %s [in module %s]"), - paddress (gdbarch, (CORE_ADDR) pc), sect_offset_str (die->sect_off), - objfile_name (objfile)); - return; - } - /* Count parameters at the caller. */ nparams = 0; @@ -10348,7 +10332,15 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu) struct call_site, sizeof (*call_site) + sizeof (call_site->parameter[0]) * nparams)) struct call_site (pc, cu->per_cu, per_objfile); - *slot = call_site; + + if (!cu->call_site_htab.emplace (call_site).second) + { + complaint (_("Duplicate PC %s for DW_TAG_call_site " + "DIE %s [in module %s]"), + paddress (gdbarch, (CORE_ADDR) pc), sect_offset_str (die->sect_off), + objfile_name (objfile)); + return; + } /* We never call the destructor of call_site, so we must ensure it is trivially destructible. */ diff --git a/gdb/symtab.c b/gdb/symtab.c index 0aa7321..edc19ff 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -396,42 +396,35 @@ linetable_entry::pc (const struct objfile *objfile) const call_site * compunit_symtab::find_call_site (CORE_ADDR pc) const { - if (m_call_site_htab == nullptr) - return nullptr; - CORE_ADDR delta = this->objfile ()->text_section_offset (); - unrelocated_addr unrelocated_pc = (unrelocated_addr) (pc - delta); - struct call_site call_site_local (unrelocated_pc, nullptr, nullptr); - void **slot - = htab_find_slot (m_call_site_htab, &call_site_local, NO_INSERT); - if (slot != nullptr) - return (call_site *) *slot; + if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (pc - delta)); + it != m_call_site_htab->end ()) + return *it; /* See if the arch knows another PC we should try. On some platforms, GCC emits a DWARF call site that is offset from the actual return location. */ struct gdbarch *arch = objfile ()->arch (); CORE_ADDR new_pc = gdbarch_update_call_site_pc (arch, pc); + if (pc == new_pc) return nullptr; - unrelocated_pc = (unrelocated_addr) (new_pc - delta); - call_site new_call_site_local (unrelocated_pc, nullptr, nullptr); - slot = htab_find_slot (m_call_site_htab, &new_call_site_local, NO_INSERT); - if (slot == nullptr) - return nullptr; + if (auto it = m_call_site_htab->find (static_cast<unrelocated_addr> (new_pc - delta)); + it != m_call_site_htab->end ()) + return *it; - return (call_site *) *slot; + return nullptr; } /* See symtab.h. */ void -compunit_symtab::set_call_site_htab (htab_up call_site_htab) +compunit_symtab::set_call_site_htab (call_site_htab_t &&call_site_htab) { gdb_assert (m_call_site_htab == nullptr); - m_call_site_htab = call_site_htab.release (); + m_call_site_htab = new call_site_htab_t (std::move (call_site_htab)); } /* See symtab.h. */ @@ -500,8 +493,7 @@ void compunit_symtab::finalize () { this->forget_cached_source_info (); - if (m_call_site_htab != nullptr) - htab_delete (m_call_site_htab); + delete m_call_site_htab; } /* The relocated address of the minimal symbol, using the section diff --git a/gdb/symtab.h b/gdb/symtab.h index ef2ff5e..f285138 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -24,6 +24,7 @@ #include <vector> #include <string> #include <set> +#include "dwarf2/call-site.h" #include "gdbsupport/gdb_vecs.h" #include "gdbtypes.h" #include "gdbsupport/gdb_obstack.h" @@ -1947,7 +1948,7 @@ struct compunit_symtab symtab *primary_filetab () const; /* Set m_call_site_htab. */ - void set_call_site_htab (htab_up call_site_htab); + void set_call_site_htab (call_site_htab_t &&call_site_htab); /* Find call_site info for PC. */ call_site *find_call_site (CORE_ADDR pc) const; @@ -2014,7 +2015,7 @@ struct compunit_symtab unsigned int m_epilogue_unwind_valid : 1; /* struct call_site entries for this compilation unit or NULL. */ - htab_t m_call_site_htab; + call_site_htab_t *m_call_site_htab; /* The macro table for this symtab. Like the blockvector, this is shared between different symtabs in a given compilation unit. |