summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}