diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-05-16 17:53:31 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-05-16 17:53:31 -0400 |
commit | 6561773f763d40c00a115b53493ecf2d4f425d0d (patch) | |
tree | ad1ce699145f8d065eb3a68e9d2e6f486ef9dc23 | |
parent | 600db44c1ae1bb5b3b638dda1d8b25e14a332270 (diff) | |
download | systemtap-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-- | ChangeLog | 11 | ||||
-rw-r--r-- | elaborate.cxx | 5 | ||||
-rw-r--r-- | tapsets.cxx | 110 |
3 files changed, 87 insertions, 39 deletions
@@ -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 (!). |