From aca66a36681ac7cbf7fcc2eac4dafc83d6559ef9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 16:14:08 -0700 Subject: Unify lex_cast* and avoid string copies We always use lex_cast either to string or from string, so I made that explicit, and got rid of some string copies in the process. There was also stringify(), which was redundant to lex_cast. We also always used lex_cast_hex to string, so that's now hard-coded and again eliminated a string copy. For lex_cast_qstring, there's no need to write the streamify the input, so a specialization now operates directly on the input. Hopefully this is a bit cleaner, and I do measure it to be a little faster on scripts with many probes. --- tapsets.cxx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 9651426e..d5c89a02 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1845,7 +1845,7 @@ dwarf_var_expanding_visitor::visit_target_symbol_saved_return (target_symbol* e) string aname = (string("_dwarf_tvar_") + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); vardecl* vd = new vardecl; vd->name = aname; vd->tok = e->tok; @@ -2256,7 +2256,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); try { @@ -2322,7 +2322,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } @@ -2568,7 +2568,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); // Synthesize a function. functiondecl *fdecl = new functiondecl; @@ -2594,7 +2594,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } @@ -2707,7 +2707,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, // Range limit maxactive() value if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX)) throw semantic_error ("maxactive value out of range [0," - + lex_cast(USHRT_MAX) + "]", + + lex_cast(USHRT_MAX) + "]", q.base_loc->tok); // Expand target variables in the probe body @@ -2764,7 +2764,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, { retro_name += ("@" + string (filename)); if (line > 0) - retro_name += (":" + lex_cast (line)); + retro_name += (":" + lex_cast (line)); } comps.push_back (new probe_point::component @@ -3364,7 +3364,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) cast->tok = e->tok; cast->operand = fc; cast->components = e->components; - cast->type = probe_name + "_arg" + lex_cast(argno); + cast->type = probe_name + "_arg" + lex_cast(argno); cast->module = process_name; cast->visit(this); @@ -4252,7 +4252,7 @@ uprobe_derived_probe::uprobe_derived_probe (const string& function, { retro_name += ("@" + string (filename)); if (line > 0) - retro_name += (":" + lex_cast (line)); + retro_name += (":" + lex_cast (line)); } comps.push_back (new probe_point::component @@ -5388,7 +5388,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) string fname = (string(lvalue ? "_tracepoint_tvar_set" : "_tracepoint_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); fdecl->name = fname; fdecl->body = ec; @@ -5427,7 +5427,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } -- cgit From b74789646bfe59131327716357c8b7c1521fa14a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 19:09:50 -0700 Subject: PR10572: Allow duplicate function names in a CU We can't assume that a given function name will only appear once in a CU. In C++, two functions may have the same name in different classes or namespaces, or even in the same scope with overloaded parameters. Even in C, the compiler may generate multiple copies of a single function with different optimizations. We now use a multimap for function names, so we shouldn't miss any. * dwflpp.h (cu_type_cache_t, mod_cu_type_cache_t): New typedef to keep a normal map for the global_alias_cache. (cu_function_cache_t): Use a multimap for function names. * dwflpp.cxx (dwflpp::iterate_over_functions): Walk over the range of exactly-matching functions. * tapsets.cxx (query_dwarf_func): Don't abort after seeing an exact match -- there could be more to come. --- tapsets.cxx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'tapsets.cxx') 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)); } } -- cgit From 7fdd3e2c61874abd631de5038d846dffb6f5bc5f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 11:32:59 -0700 Subject: PR10573: Squash duplicate inline instances In C++, identical functions included in multiple CUs will get merged at link time into a single instance. We need to make sure that inlines within those merged functions are not probed multiple times. * tapsets.cxx (inline_instance_info::operator<): Used for set support. (dwarf_query::handle_query_module): Clear inline_dupes on each module. (query_dwarf_inline_instance): Squash this inline instance if it's already in the inline_dupes set. --- tapsets.cxx | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index c136ea0f..15491d55 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -552,6 +552,10 @@ struct dwarf_query : public base_query // Track addresses we've already seen in a given module set alias_dupes; + // Track inlines we've already seen as well + // NB: this can't be compared just by entrypc, as inlines can overlap + set inline_dupes; + // Extracted parameters. string function_val; @@ -850,6 +854,7 @@ dwarf_query::handle_query_module() // reset the dupe-checking for each new module alias_dupes.clear(); + inline_dupes.clear(); if (dw.mod_info->dwarf_status == info_present) query_module_dwarf(); @@ -1248,6 +1253,22 @@ query_srcfile_line (const dwarf_line_t& line, void * arg) } +bool +inline_instance_info::operator<(const inline_instance_info& other) const +{ + if (entrypc != other.entrypc) + return entrypc < other.entrypc; + + if (decl_line != other.decl_line) + return decl_line < other.decl_line; + + int cmp = name.compare(other.name); + if (!cmp) + cmp = strcmp(decl_file, other.decl_file); + return cmp < 0; +} + + static int query_dwarf_inline_instance (Dwarf_Die * die, void * arg) { @@ -1275,7 +1296,11 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) inl.entrypc = entrypc; q->dw.function_file (&inl.decl_file); q->dw.function_line (&inl.decl_line); - q->filtered_inlines.push_back(inl); + + // make sure that this inline hasn't already + // been matched from a different CU + if (q->inline_dupes.insert(inl).second) + q->filtered_inlines.push_back(inl); } } return DWARF_CB_OK; -- cgit From 789448a36f57e53cc6a1878f7637998b0f15652c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 12:00:10 -0700 Subject: Fetch the blacklist section only when needed We only check blacklisting on kernel probes, so it's a waste to dig up the section name otherwise. * dwflpp.cxx (dwflpp::blacklisted_p): Lookup the section directly. (relocate_address::relocate_address): Don't do blacklisting here. * tapsets.cxx (dwarf_query::add_probe_point): Don't carry the blacklist section directly anymore. --- tapsets.cxx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 15491d55..e0768868 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -965,12 +965,11 @@ dwarf_query::add_probe_point(const string& funcname, { string reloc_section; // base section for relocation purposes Dwarf_Addr reloc_addr; // relocated - string blacklist_section; // linking section for blacklist purposes const string& module = dw.module_name; // "kernel" or other assert (! has_absolute); // already handled in dwarf_builder::build() - reloc_addr = dw.relocate_address(addr, reloc_section, blacklist_section); + reloc_addr = dw.relocate_address(addr, reloc_section); if (sess.verbose > 1) { @@ -982,12 +981,11 @@ dwarf_query::add_probe_point(const string& funcname, else if (has_process) clog << " process=" << module; if (reloc_section != "") clog << " reloc=" << reloc_section; - if (blacklist_section != "") clog << " section=" << blacklist_section; clog << " pc=0x" << hex << addr << dec; } bool bad = dw.blacklisted_p (funcname, filename, line, module, - blacklist_section, addr, has_return); + addr, has_return); if (sess.verbose > 1) clog << endl; -- cgit