diff options
-rw-r--r-- | elaborate.cxx | 3 | ||||
-rw-r--r-- | elaborate.h | 5 | ||||
-rw-r--r-- | staptree.h | 1 | ||||
-rw-r--r-- | tapsets.cxx | 86 | ||||
-rw-r--r-- | translate.cxx | 7 |
5 files changed, 43 insertions, 59 deletions
diff --git a/elaborate.cxx b/elaborate.cxx index 34e6ab16..323261c7 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -3392,6 +3392,9 @@ typeresolution_info::visit_symbol (symbol* e) void typeresolution_info::visit_target_symbol (target_symbol* e) { + if (!e->probe_context_var.empty()) + return; + // This occurs only if a target symbol was not resolved over in // tapset.cxx land, that error was properly suppressed, and the // later unused-expression-elimination pass didn't get rid of it diff --git a/elaborate.h b/elaborate.h index 0ad5b4b2..d927177b 100644 --- a/elaborate.h +++ b/elaborate.h @@ -129,6 +129,11 @@ struct derived_probe: public probe void printsig_nested (std::ostream &o) const; virtual void collect_derivation_chain (std::vector<probe*> &probes_list); + virtual void print_dupe_stamp(std::ostream&) {} + // To aid duplication elimination, print a stamp which uniquely identifies + // the code that will be added to the probe body. (Doesn't need to be the + // actual code...) + virtual void emit_probe_context_vars (translator_output*) {} // From within unparser::emit_common_header, add any extra variables // to this probe's context locals. @@ -231,6 +231,7 @@ struct target_symbol: public symbol }; std::string base_name; std::vector<std::pair<component_type, std::string> > components; + std::string probe_context_var; semantic_error* saved_conversion_error; target_symbol(): saved_conversion_error (0) {} void print (std::ostream& o) const; diff --git a/tapsets.cxx b/tapsets.cxx index c4348a29..0ff26be8 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -8671,6 +8671,7 @@ struct mark_derived_probe: public derived_probe bool target_symbol_seen; void join_group (systemtap_session& s); + void print_dupe_stamp (ostream& o); void emit_probe_context_vars (translator_output* o); void initialize_probe_context_vars (translator_output* o); void printargs (std::ostream &o) const; @@ -8774,36 +8775,9 @@ mark_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // Remember that we've seen a target variable. target_symbol_seen = true; - // Synthesize a function. - functiondecl *fdecl = new functiondecl; - fdecl->tok = e->tok; - embeddedcode *ec = new embeddedcode; - ec->tok = e->tok; - - string fname = string("_mark_tvar_get") - + "_" + e->base_name.substr(1) - + "_" + lex_cast<string>(tick++); - - if (mark_args[argnum-1]->stp_type == pe_long) - ec->code = string("THIS->__retvalue = CONTEXT->locals[0].") - + probe_name + string(".__mark_arg") - + lex_cast<string>(argnum) + string (";"); - else - ec->code = string("strlcpy (THIS->__retvalue, CONTEXT->locals[0].") - + probe_name + string(".__mark_arg") - + lex_cast<string>(argnum) + string (", MAXSTRINGLEN);"); - ec->code += "/* pure */"; - fdecl->name = fname; - fdecl->body = ec; - fdecl->type = mark_args[argnum-1]->stp_type; - sess.functions[fdecl->name]=fdecl; - - // Synthesize a functioncall. - functioncall* n = new functioncall; - n->tok = e->tok; - n->function = fname; - n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session - provide (n); + e->probe_context_var = "__mark_arg" + lex_cast<string>(argnum); + e->type = mark_args[argnum-1]->stp_type; + provide (e); } @@ -9054,6 +9028,15 @@ mark_derived_probe::join_group (systemtap_session& s) void +mark_derived_probe::print_dupe_stamp (ostream& o) +{ + if (target_symbol_seen) + for (unsigned i = 0; i < mark_args.size(); i++) + o << mark_args[i]->c_type << " __mark_arg" << (i+1) << endl; +} + + +void mark_derived_probe::emit_probe_context_vars (translator_output* o) { // If we haven't seen a target symbol for this probe, quit. @@ -9391,6 +9374,7 @@ struct tracepoint_derived_probe: public derived_probe void build_args(dwflpp& dw, Dwarf_Die& func_die); void printargs (std::ostream &o) const; void join_group (systemtap_session& s); + void print_dupe_stamp(ostream& o); void emit_probe_context_vars (translator_output* o); }; @@ -9480,33 +9464,10 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) if (e->components.empty()) { - // Synthesize a simple function to grab the parameter - functiondecl *fdecl = new functiondecl; - fdecl->tok = e->tok; - embeddedcode *ec = new embeddedcode; - ec->tok = e->tok; - - string fname = (string("_tracepoint_tvar_get") - + "_" + e->base_name.substr(1) - + "_" + lex_cast<string>(tick++)); - - fdecl->name = fname; - fdecl->body = ec; - fdecl->type = pe_long; - - ec->code = (string("THIS->__retvalue = CONTEXT->locals[0].") - + probe_name + string(".__tracepoint_arg_") - + arg->name + string (";/* pure */")); - - dw.sess.functions[fdecl->name] = fdecl; - - // Synthesize a functioncall. - functioncall* n = new functioncall; - n->tok = e->tok; - n->function = fname; - n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session - - provide (n); + // Just grab the value from the probe locals + e->probe_context_var = "__tracepoint_arg_" + arg->name; + e->type = pe_long; + provide (e); } else { @@ -9629,7 +9590,6 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) } else if (e->base_name == "$$vars" || e->base_name == "$$parms") { - target_symbol *tsym = new target_symbol; print_format* pf = new print_format; // Convert $$vars to sprintf of a list of vars which we recursively evaluate @@ -9653,6 +9613,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) if (i > 0) pf->raw_components += " "; pf->raw_components += args[i].name; + target_symbol *tsym = new target_symbol; tsym->tok = e->tok; tsym->base_name = "$" + args[i].name; @@ -9883,6 +9844,15 @@ tracepoint_derived_probe::join_group (systemtap_session& s) void +tracepoint_derived_probe::print_dupe_stamp(ostream& o) +{ + for (unsigned i = 0; i < args.size(); i++) + if (args[i].used) + o << "__tracepoint_arg_" << args[i].name << endl; +} + + +void tracepoint_derived_probe::emit_probe_context_vars (translator_output* o) { for (unsigned i = 0; i < args.size(); i++) diff --git a/translate.cxx b/translate.cxx index cab37487..c42097bb 100644 --- a/translate.cxx +++ b/translate.cxx @@ -918,6 +918,7 @@ c_unparser::emit_common_header () ostringstream oss; oss << "c->statp = & time_" << dp->basest()->name << ";" << endl; // -t anti-dupe oss << "# needs_global_locks: " << dp->needs_global_locks () << endl; + dp->print_dupe_stamp (oss); dp->body->print(oss); // NB: dependent probe conditions *could* be listed here, but don't need to be. // That's because they're only dependent on the probe body, which is already @@ -1507,6 +1508,7 @@ c_unparser::emit_probe (derived_probe* v) // be very different with or without -t. oss << "c->statp = & time_" << v->basest()->name << ";" << endl; + v->print_dupe_stamp (oss); v->body->print(oss); // Since the generated C changes based on whether or not the probe @@ -3488,7 +3490,10 @@ c_unparser_assignment::visit_symbol (symbol *e) void c_unparser::visit_target_symbol (target_symbol* e) { - throw semantic_error("cannot translate general target-symbol expression", e->tok); + if (!e->probe_context_var.empty()) + o->line() << "l->" << e->probe_context_var; + else + throw semantic_error("cannot translate general cast expression", e->tok); } |