summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-05-16 17:53:31 -0400
committerFrank Ch. Eigler <fche@elastic.org>2008-05-16 17:53:31 -0400
commit6561773f763d40c00a115b53493ecf2d4f425d0d (patch)
treead1ce699145f8d065eb3a68e9d2e6f486ef9dc23
parent600db44c1ae1bb5b3b638dda1d8b25e14a332270 (diff)
downloadsystemtap-steved-6561773f763d40c00a115b53493ecf2d4f425d0d.tar.gz
systemtap-steved-6561773f763d40c00a115b53493ecf2d4f425d0d.tar.xz
systemtap-steved-6561773f763d40c00a115b53493ecf2d4f425d0d.zip
PR5643: function caching for much faster syscall.* pass-2 processing
-rw-r--r--ChangeLog11
-rw-r--r--elaborate.cxx5
-rw-r--r--tapsets.cxx110
3 files changed, 87 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 005af837..24fa8e3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-05-16 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 5643
+ * tapsets.cxx (cu_function_cache_t): Reorganize into
+ mod:cu->function->DIE lookup table. Consider merging into symtab
+ later.
+ (mark_dwarf_redudancies): Adapt.
+ (iterate_over_functions): Rewrite.
+ (dwarf_builder::build): Cache kprobes etc. symbol addresses.
+ * elaborate.cxx (systemtap_session ctor): Clear additional POD fields.
+
2008-05-15 David Smith <dsmith@redhat.com>
* main.cxx (setup_signals): New function.
diff --git a/elaborate.cxx b/elaborate.cxx
index 306baff1..0e454937 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -1188,7 +1188,10 @@ systemtap_session::systemtap_session ():
hrtimer_derived_probes(0),
perfmon_derived_probes(0),
procfs_derived_probes(0),
- op (0), up (0)
+ op (0), up (0),
+ sym_kprobes_text_start (0),
+ sym_kprobes_text_end (0),
+ sym_stext (0)
{
}
diff --git a/tapsets.cxx b/tapsets.cxx
index 9528066f..96a93019 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -535,7 +535,8 @@ module_cache
};
typedef struct module_cache module_cache_t;
-typedef map<string, vector<Dwarf_Die>*> cu_function_cache_t;
+typedef map<string,Dwarf_Die> cu_function_cache_t;
+typedef map<string,cu_function_cache_t*> mod_cu_function_cache_t; // module:cu -> function -> die
struct
symbol_table
@@ -1111,40 +1112,18 @@ struct dwflpp
// -----------------------------------------------------------------
- cu_function_cache_t cu_function_cache;
+ mod_cu_function_cache_t cu_function_cache;
static int cu_function_caching_callback (Dwarf_Die* func, void *arg)
{
- vector<Dwarf_Die>* v = static_cast<vector<Dwarf_Die>*>(arg);
- v->push_back (* func);
+ cu_function_cache_t* v = static_cast<cu_function_cache_t*>(arg);
+ string function_name = dwarf_diename(func);
+ (*v)[function_name] = * func;
return DWARF_CB_OK;
}
int iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
- void * data)
- {
- int rc = DWARF_CB_OK;
- assert (module);
- assert (cu);
-
- string key = module_name + ":" + cu_name;
- vector<Dwarf_Die>* v = cu_function_cache[key];
- if (v == 0)
- {
- v = new vector<Dwarf_Die>;
- cu_function_cache[key] = v;
- dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
- }
-
- for (unsigned i=0; i<v->size(); i++)
- {
- Dwarf_Die die = v->at(i);
- rc = (*callback)(& die, data);
- if (rc != DWARF_CB_OK) break;
- }
- return rc;
- }
-
+ void * data);
bool has_single_line_record (dwarf_query * q, char const * srcfile, int lineno);
@@ -2489,6 +2468,58 @@ dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int linen
}
+int
+dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, void * arg),
+ void * data)
+{
+ int rc = DWARF_CB_OK;
+ assert (module);
+ assert (cu);
+ dwarf_query * q = static_cast<dwarf_query *>(data);
+
+ string key = module_name + ":" + cu_name;
+ cu_function_cache_t *v = cu_function_cache[key];
+ if (v == 0)
+ {
+ v = new cu_function_cache_t;
+ cu_function_cache[key] = v;
+ dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
+ if (q->sess.verbose > 4)
+ clog << "function cache " << key << " size " << v->size() << endl;
+ }
+
+ string subkey = q->function;
+ if (v->find(subkey) != v->end())
+ {
+ Dwarf_Die die = v->at(subkey);
+ if (q->sess.verbose > 4)
+ clog << "function cache " << key << " hit " << subkey << endl;
+ return (*callback)(& die, data);
+ }
+ else if (name_has_wildcard (subkey))
+ {
+ for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
+ {
+ string func_name = it->first;
+ Dwarf_Die die = it->second;
+ if (function_name_matches_pattern (func_name, subkey))
+ {
+ if (q->sess.verbose > 4)
+ clog << "function cache " << key << " match " << func_name << " vs " << subkey << endl;
+
+ rc = (*callback)(& die, data);
+ if (rc != DWARF_CB_OK) break;
+ }
+ }
+ }
+ else // not a wildcard and no match in this CU
+ {
+ // do nothing
+ }
+ return rc;
+}
+
+
struct dwarf_builder: public derived_probe_builder
{
@@ -4584,10 +4615,13 @@ dwarf_builder::build(systemtap_session & sess,
kern_dw->iterate_over_modules(&query_kernel_module, &km);
if (km)
{
- sess.sym_kprobes_text_start = lookup_symbol_address (km, "__kprobes_text_start");
- sess.sym_kprobes_text_end = lookup_symbol_address (km, "__kprobes_text_end");
- sess.sym_stext = lookup_symbol_address (km, "_stext");
-
+ if (! sess.sym_kprobes_text_start)
+ sess.sym_kprobes_text_start = lookup_symbol_address (km, "__kprobes_text_start");
+ if (! sess.sym_kprobes_text_end)
+ sess.sym_kprobes_text_end = lookup_symbol_address (km, "__kprobes_text_end");
+ if (! sess.sym_stext)
+ sess.sym_stext = lookup_symbol_address (km, "_stext");
+
if (sess.verbose > 2)
{
clog << "control symbols:"
@@ -4774,21 +4808,21 @@ symbol_table::mark_dwarf_redundancies(dwflpp *dw)
// vector of Dwarf_Dies, one per function.
string module_prefix = string(mod_info->name) + ":";
- cu_function_cache_t::iterator cu;
+ mod_cu_function_cache_t::iterator cu;
for (cu = dw->cu_function_cache.begin();
- cu != dw->cu_function_cache.end(); cu++)
+ cu != dw->cu_function_cache.end(); cu++)
{
string key = cu->first;
if (key.find(module_prefix) == 0)
{
// Found a compilation unit in the module of interest.
// Mark all its functions in the symbol table.
- vector<Dwarf_Die>* v = cu->second;
+ cu_function_cache_t* v = cu->second;
assert(v);
- for (unsigned f=0; f < v->size(); f++)
+ for (cu_function_cache_t::iterator fc = v->begin(); fc != v->end(); fc++)
{
- Dwarf_Die func = v->at(f);
- string func_name = dwarf_diename(&func);
+ Dwarf_Die func = fc->second;
+ string func_name = fc->first; // == dwarf_diename(&func);
// map_by_name[func_name]->die = func;
map<string, func_info*>::iterator i = map_by_name.find(func_name);
// Func names can show up in the dwarf but not the symtab (!).