diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | elaborate.cxx | 20 | ||||
-rw-r--r-- | elaborate.h | 7 | ||||
-rw-r--r-- | staptree.cxx | 13 | ||||
-rw-r--r-- | staptree.h | 5 | ||||
-rw-r--r-- | tapsets.cxx | 8 | ||||
-rw-r--r-- | translate.cxx | 81 | ||||
-rw-r--r-- | translate.h | 2 |
8 files changed, 106 insertions, 53 deletions
@@ -1,3 +1,26 @@ +2006-05-18 Frank Ch. Eigler <fche@elastic.org> + + Organize "-t" output by script/parse level probes rather than + derived-probes. + * elaborate.cxx (derived_probe ctor): Remove name field setting. + (alias_derived_probe): New class. + (alias_expandion_builder::build): Create an instance of the above + instead of parse-tree-level plain probe. + * elaborate.h: Corresponding changes. + (derived_probe::basest): Define. + * staptree.cxx (probe ctor): Set new name field. + * staptree.h (probe): Corresponding changes. + (probe::basest): New field. + * tapsets.cxx (emit_probe_prologue, emit_probe_entries): + Switch to basest() probe name for Stat instance. + (dwarf_derived_probe ctor): Stash away base probe. + * translate.cxx (unparser::emit_probe): Remove index + operand, just use probe name to generate symbols. + (emit_module_init): Reorganize -t output in unregister functions. + (translate_pass): Remove unparser::current_probenum field and all + uses. + * translate.h: Corresponding changes. + 2006-05-18 Li Guanglei <guanglei@cn.ibm.com> * tapset/tskschedule.stp: deleted, merge into scheduler.stp diff --git a/elaborate.cxx b/elaborate.cxx index abb91540..195f805a 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -42,13 +42,9 @@ lex_cast(IN const & in) // ------------------------------------------------------------------------ -unsigned derived_probe::last_probeidx = 0; - derived_probe::derived_probe (probe *p): base (p) { - this->name = string ("probe_") + lex_cast<string>(last_probeidx ++); - if (p) { this->locations = p->locations; @@ -61,8 +57,6 @@ derived_probe::derived_probe (probe *p): derived_probe::derived_probe (probe *p, probe_point *l): base (p) { - this->name = string ("probe_") + lex_cast<string>(last_probeidx ++); - if (l) this->locations.push_back (l); @@ -306,6 +300,18 @@ match_node::find_and_build (systemtap_session& s, // Alias probes // ------------------------------------------------------------------------ +struct alias_derived_probe: public derived_probe +{ + alias_derived_probe (probe* base): derived_probe (base) {} + + // alias probes should be ultimately expanded to other derived_probe + // types, and not themselves emitted. + void emit_registrations (translator_output* o) { throw semantic_error ("inappropriate", this->tok); } + void emit_deregistrations (translator_output* o) { throw semantic_error ("inappropriate", this->tok); } + void emit_probe_entries (translator_output* o) { throw semantic_error ("inappropriate", this->tok); } +}; + + struct alias_expansion_builder : public derived_probe_builder @@ -326,7 +332,7 @@ alias_expansion_builder // alias_expansion_probe so that the expansion loop recognizes it as // such and re-expands its expansion. - probe * n = new probe(); + probe * n = new alias_derived_probe (use); n->body = new block(); // The new probe gets the location list of the alias, diff --git a/elaborate.h b/elaborate.h index 2255037e..ed8570f3 100644 --- a/elaborate.h +++ b/elaborate.h @@ -112,12 +112,7 @@ struct derived_probe: public probe derived_probe (probe* b); derived_probe (probe* b, probe_point* l); probe* base; // the original parsed probe - -private: - static unsigned last_probeidx; - -public: - std::string name; + virtual probe* basest () { return base->basest(); } virtual ~derived_probe () {} diff --git a/staptree.cxx b/staptree.cxx index 75c2c17d..676a4ec3 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -38,6 +38,17 @@ lex_cast_qstring(IN const & in) } +template <typename OUT, typename IN> inline OUT +lex_cast(IN const & in) +{ + stringstream ss; + OUT out; + if (!(ss << in && ss >> out)) + throw runtime_error("bad lexical cast"); + return out; +} + + expression::expression (): type (pe_unknown), tok (0) { @@ -101,9 +112,11 @@ probe_point::probe_point (): } +unsigned probe::last_probeidx = 0; probe::probe (): body (0), tok (0) { + this->name = string ("probe_") + lex_cast<string>(last_probeidx ++); } @@ -577,7 +577,12 @@ struct probe probe (); void print (std::ostream& o) const; virtual void printsig (std::ostream &o) const; + virtual probe* basest () { return this; } virtual ~probe() {} +private: + static unsigned last_probeidx; +public: + std::string name; }; struct probe_alias: public probe diff --git a/tapsets.cxx b/tapsets.cxx index d562677b..9cb93e68 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -151,7 +151,7 @@ derived_probe::emit_probe_epilogue (translator_output* o) o->newline() << "int64_t cycles_elapsed = (cycles_atend > cycles_atstart)"; o->newline(1) << "? (int64_t) (cycles_atend - cycles_atstart)"; o->newline() << ": (int64_t) (~(cycles_t)0) - cycles_atstart + cycles_atend + 1;"; - o->newline() << "_stp_stat_add(time_" << name << ",cycles_elapsed);"; + o->newline() << "_stp_stat_add(time_" << basest()->name << ",cycles_elapsed);"; o->indent(-1); o->newline(-1) << "}"; o->newline() << "#endif"; @@ -215,7 +215,7 @@ void be_derived_probe::emit_probe_entries (translator_output* o) { o->newline() << "#ifdef STP_TIMING"; - o->newline() << "static __cacheline_aligned Stat " << "time_" << name << ";"; + o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";"; o->newline() << "#endif"; for (unsigned i=0; i<locations.size(); i++) @@ -2756,7 +2756,7 @@ dwarf_derived_probe::add_probe_point(string const & funcname, dwarf_derived_probe::dwarf_derived_probe (Dwarf_Die *scope_die, Dwarf_Addr addr, dwarf_query & q) - : derived_probe (NULL), + : derived_probe (q.base_probe, 0 /* location-less */), has_return (q.has_return) { string module_name(q.dw.module_name); @@ -3080,7 +3080,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o) o->newline(); o->newline() << "#ifdef STP_TIMING"; - o->newline() << "static __cacheline_aligned Stat " << "time_" << name << ";"; + o->newline() << "static __cacheline_aligned Stat " << "time_" << basest()->name << ";"; o->newline() << "#endif"; // Construct a single entry function, and a struct kprobe pointing into diff --git a/translate.cxx b/translate.cxx index 3b656815..d107423e 100644 --- a/translate.cxx +++ b/translate.cxx @@ -64,7 +64,6 @@ struct c_unparser: public unparser, public visitor translator_output* o; derived_probe* current_probe; - unsigned current_probenum; functiondecl* current_function; unsigned tmpvar_counter; unsigned label_counter; @@ -83,7 +82,7 @@ struct c_unparser: public unparser, public visitor void emit_module_exit (); void emit_function (functiondecl* v); void emit_locks (const varuse_collecting_visitor& v); - void emit_probe (derived_probe* v, unsigned i); + void emit_probe (derived_probe* v); void emit_unlocks (const varuse_collecting_visitor& v); // for use by stats (pmap) foreach @@ -831,7 +830,7 @@ c_unparser::emit_common_header () derived_probe* dp = session->probes[i]; // XXX: probe locals need not be recursion-nested, only function locals - o->newline() << "struct probe_" << i << "_locals {"; + o->newline() << "struct " << dp->name << "_locals {"; o->indent(1); for (unsigned j=0; j<dp->locals.size(); j++) { @@ -991,6 +990,8 @@ c_unparser::emit_module_init () // to avoid forcing the compiler to work too hard at optimizing such // a silly function. A "don't optimize this function" pragma could // come in handy too. + + set<string> basest_names; for (unsigned i=0; i<session->probes.size(); i++) { o->newline() << "static noinline int register_probe_" << i << " (void) {"; @@ -1021,26 +1022,32 @@ c_unparser::emit_module_init () o->newline() << "noinline void unregister_probe_" << i << " (void) {"; o->indent(1); session->probes[i]->emit_deregistrations (o); - o->newline() << "#ifdef STP_TIMING"; - o->newline(1) << "{"; - o->newline() << "const char *probe_point = " << - lex_cast_qstring (*session->probes[i]->locations[0]) << ";"; - o->newline() << "struct stat_data *stats = _stp_stat_get (time_" - << session->probes[i]->name << ", 0);"; - o->newline() << "int64_t avg = 0;"; - o->newline() << "const char *error;"; - o->newline() << "if (stats->count) avg = _stp_div64(&error, stats->sum, stats->count);"; - o->newline() << "_stp_printf ("; - o->newline() << "\"probe at " << session->probes[i]->tok->location - << " (%s)\"" ; - o->newline() << "\" %lld@%lld (%lld <= t <= %lld)\\n\","; - o->newline() << "probe_point, stats->count, avg, stats->min, stats->max);"; - o->newline() << "_stp_print_flush();"; - o->newline(-1) << "}"; - o->newline() << "#endif"; + + string nm = session->probes[i]->basest()->name; + if (basest_names.find(nm) == basest_names.end()) + { + basest_names.insert (nm); + o->newline() << "#ifdef STP_TIMING"; + o->newline() << "{"; + o->newline(1) << "const char *probe_point = " + << lex_cast_qstring (*session->probes[i]->basest()->locations[0]) << ";"; + o->newline() << "const char *decl_location = " + << lex_cast_qstring (session->probes[i]->basest()->tok->location) << ";"; + o->newline() << "struct stat_data *stats = _stp_stat_get (time_" << session->probes[i]->basest()->name + << ", 0);"; + o->newline() << "const char *error;"; + o->newline() << "if (stats->count) {"; + o->newline(1) << "int64_t avg = _stp_div64 (&error, stats->sum, stats->count);"; + o->newline() << "_stp_printf (\"probe %s (%s), %lld hits, %lld min %lld avg %lld max cycles\\n\","; + o->newline() << "probe_point, decl_location, (long long) stats->count, (long long) stats->min, (long long) avg, (long long) stats->max);"; + o->newline() << "_stp_print_flush();"; + o->newline(-1) << "}"; + o->newline(-1) << "}"; + o->newline() << "#endif"; + } o->newline(-1) << "}"; } - + o->newline(); o->newline() << "int systemtap_module_init (void) {"; o->newline(1) << "int rc = 0;"; @@ -1073,13 +1080,20 @@ c_unparser::emit_module_init () } // initialize each Stat used for timing information - o->newline() << "#ifdef STP_TIMING"; - for (unsigned i=0; i<session->probes.size(); i++) - { - o->newline() << "time_" << session->probes[i]->name - << " = _stp_stat_init (HIST_NONE);"; - } - o->newline() << "#endif"; + { + o->newline() << "#ifdef STP_TIMING"; + set<string> basest_names; + for (unsigned i=0; i<session->probes.size(); i++) + { + string nm = session->probes[i]->basest()->name; + if (basest_names.find(nm) == basest_names.end()) + { + o->newline() << "time_" << nm << " = _stp_stat_init (HIST_NONE);"; + basest_names.insert (nm); + } + } + o->newline() << "#endif"; + } for (unsigned i=0; i<session->probes.size(); i++) { @@ -1203,7 +1217,6 @@ c_unparser::emit_function (functiondecl* v) << " (struct context* __restrict__ c) {"; o->indent(1); this->current_probe = 0; - this->current_probenum = 0; this->current_function = v; this->tmpvar_counter = 0; @@ -1249,18 +1262,17 @@ c_unparser::emit_function (functiondecl* v) void -c_unparser::emit_probe (derived_probe* v, unsigned i) +c_unparser::emit_probe (derived_probe* v) { this->current_function = 0; this->current_probe = v; - this->current_probenum = i; this->tmpvar_counter = 0; - o->newline() << "static void probe_" << i << " (struct context * __restrict__ c) {"; + o->newline() << "static void " << v->name << " (struct context * __restrict__ c) {"; o->indent(1); // initialize frame pointer - o->newline() << "struct probe_" << i << "_locals * __restrict__ l ="; + o->newline() << "struct " << v->name << "_locals * __restrict__ l ="; o->newline(1) << "& c->locals[0]." << v->name << ";"; o->newline(-1) << "(void) l;"; // make sure "l" is marked used @@ -1297,7 +1309,6 @@ c_unparser::emit_probe (derived_probe* v, unsigned i) o->newline(-1) << "}\n"; this->current_probe = 0; - this->current_probenum = 0; // not essential v->emit_probe_entries (o); } @@ -3890,7 +3901,7 @@ translate_pass (systemtap_session& s) for (unsigned i=0; i<s.probes.size(); i++) { s.op->newline(); - s.up->emit_probe (s.probes[i], i); + s.up->emit_probe (s.probes[i]); } s.op->newline(); diff --git a/translate.h b/translate.h index f756ee62..ab0ad98b 100644 --- a/translate.h +++ b/translate.h @@ -85,7 +85,7 @@ struct unparser // .... // } - virtual void emit_probe (derived_probe* v, unsigned i) = 0; + virtual void emit_probe (derived_probe* v) = 0; // void probe_NUMBER (struct context* c) { // ... lifecycle // .... |