summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-04-06 16:11:30 -0700
committerJosh Stone <jistone@redhat.com>2009-04-06 16:48:11 -0700
commit3e3bd7b6b9dd2ba282990f39d60e3ad5ecfec023 (patch)
treef103f40f27ccc9ef67cd9780a7bb307a7d43bb53
parentb4c34c261909065b97dfccfd6df996897457193c (diff)
downloadsystemtap-steved-3e3bd7b6b9dd2ba282990f39d60e3ad5ecfec023.tar.gz
systemtap-steved-3e3bd7b6b9dd2ba282990f39d60e3ad5ecfec023.tar.xz
systemtap-steved-3e3bd7b6b9dd2ba282990f39d60e3ad5ecfec023.zip
PR10026: Read marker/tracepoint args directly
We already stash the context variables for markers and tracepoints into the locals for the probe body, but then we were using separate functions to read those locals for each particular probe body. This patch instead teaches the unparser how to emit the local name directly for those context variables. The resulting code from the translator is much simpler now.
-rw-r--r--elaborate.cxx3
-rw-r--r--elaborate.h5
-rw-r--r--staptree.h1
-rw-r--r--tapsets.cxx86
-rw-r--r--translate.cxx7
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.
diff --git a/staptree.h b/staptree.h
index 5125cd85..7e9506bb 100644
--- a/staptree.h
+++ b/staptree.h
@@ -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);
}