summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwflpp.cxx30
-rw-r--r--dwflpp.h13
-rw-r--r--tapsets.cxx10
3 files changed, 29 insertions, 24 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 3c6a106d..d55852ee 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -106,7 +106,7 @@ dwflpp::~dwflpp()
it != cu_inl_function_cache.end(); ++it)
delete it->second;
- for (mod_cu_function_cache_t::iterator it = global_alias_cache.begin();
+ for (mod_cu_type_cache_t::iterator it = global_alias_cache.begin();
it != global_alias_cache.end(); ++it)
delete it->second;
@@ -594,7 +594,7 @@ dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void *
int
dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg)
{
- cu_function_cache_t *cache = static_cast<cu_function_cache_t*>(arg);
+ cu_type_cache_t *cache = static_cast<cu_type_cache_t*>(arg);
const char *name = dwarf_diename(die);
if (!name)
@@ -616,10 +616,10 @@ dwflpp::declaration_resolve(const char *name)
if (!name)
return NULL;
- cu_function_cache_t *v = global_alias_cache[cu->addr];
+ cu_type_cache_t *v = global_alias_cache[cu->addr];
if (v == 0) // need to build the cache, just once per encountered module/cu
{
- v = new cu_function_cache_t;
+ v = new cu_type_cache_t;
global_alias_cache[cu->addr] = v;
iterate_over_globals(global_alias_caching_callback, v);
if (sess.verbose > 4)
@@ -650,8 +650,7 @@ dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg)
if (!name)
return DWARF_CB_OK;
- string function_name = name;
- (*v)[function_name] = * func;
+ v->insert(make_pair(string(name), *func));
return DWARF_CB_OK;
}
@@ -677,14 +676,19 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query *
mod_info->update_symtab(v);
}
- cu_function_cache_t::iterator it = v->find(function);
- if (it != v->end())
+ cu_function_cache_t::iterator it;
+ cu_function_cache_range_t range = v->equal_range(function);
+ if (range.first != range.second)
{
- Dwarf_Die& die = it->second;
- if (sess.verbose > 4)
- clog << "function cache " << module_name << ":" << cu_name()
- << " hit " << function << endl;
- return (*callback)(& die, q);
+ for (it = range.first; it != range.second; ++it)
+ {
+ Dwarf_Die& die = it->second;
+ if (sess.verbose > 4)
+ clog << "function cache " << module_name << ":" << cu_name()
+ << " hit " << function << endl;
+ rc = (*callback)(& die, q);
+ if (rc != DWARF_CB_OK) break;
+ }
}
else if (name_has_wildcard (function))
{
diff --git a/dwflpp.h b/dwflpp.h
index 9ed18558..431f3c4b 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -47,8 +47,17 @@ enum info_status { info_unknown, info_present, info_absent };
// module -> cu die[]
typedef unordered_map<Dwarf*, std::vector<Dwarf_Die>*> module_cu_cache_t;
+// typename -> die
+typedef unordered_map<std::string, Dwarf_Die> cu_type_cache_t;
+
+// cu die -> (typename -> die)
+typedef unordered_map<void*, cu_type_cache_t*> mod_cu_type_cache_t;
+
// function -> die
-typedef unordered_map<std::string, Dwarf_Die> cu_function_cache_t;
+typedef unordered_multimap<std::string, Dwarf_Die> cu_function_cache_t;
+typedef std::pair<cu_function_cache_t::iterator,
+ cu_function_cache_t::iterator>
+ cu_function_cache_range_t;
// cu die -> (function -> die)
typedef unordered_map<void*, cu_function_cache_t*> mod_cu_function_cache_t;
@@ -293,7 +302,7 @@ private:
* cache is indexed by name. If other declaration lookups were
* added to it, it would have to be indexed by name and tag
*/
- mod_cu_function_cache_t global_alias_cache;
+ mod_cu_type_cache_t global_alias_cache;
static int global_alias_caching_callback(Dwarf_Die *die, void *arg);
int iterate_over_globals (int (* callback)(Dwarf_Die *, void *),
void * data);
diff --git a/tapsets.cxx b/tapsets.cxx
index d5c89a02..c136ea0f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1319,9 +1319,6 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
clog << "checking instances of inline " << q->dw.function_name
<< "\n";
q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, q);
-
- if (q->dw.function_name_final_match (q->function))
- return DWARF_CB_ABORT;
}
else if (!q->dw.func_is_inline () && (! q->has_inline))
{
@@ -1382,14 +1379,9 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq)
func.entrypc -= q->dw.module_bias;
q->filtered_functions.push_back (func);
- if (q->dw.function_name_final_match (q->function))
- return DWARF_CB_ABORT;
}
else
assert(0);
-
- if (q->dw.function_name_final_match (q->function))
- return DWARF_CB_ABORT;
}
}
return DWARF_CB_OK;
@@ -4153,7 +4145,7 @@ module_info::update_symtab(cu_function_cache_t *funcs)
// if this function is a new alias, then
// save it to merge into the function cache
if (it->second != fi)
- new_funcs[it->second->name] = it->second->die;
+ new_funcs.insert(make_pair(it->second->name, it->second->die));
}
}