forked from Imagelibrary/binutils-gdb
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>
This commit is contained in:
@@ -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,34 +169,17 @@ 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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Return the address of the first instruction after this call. */
|
||||
/* Return the relocated (using the objfile from PER_OBJFILE) address of the
|
||||
first instruction after this call. */
|
||||
|
||||
CORE_ADDR pc () const;
|
||||
|
||||
/* Return the unrelocated address of the first instruction after this
|
||||
call. */
|
||||
|
||||
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
|
||||
throw NO_ENTRY_VALUE_ERROR. */
|
||||
@@ -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 */
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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. */
|
||||
|
||||
30
gdb/symtab.c
30
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
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user