summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authordsmith <dsmith>2006-12-13 20:56:19 +0000
committerdsmith <dsmith>2006-12-13 20:56:19 +0000
commit8fc05e57c1d6468548444a923ef24065a4c8caeb (patch)
tree94f70f3ad0dee38b670a63300da4ef4a8ad6fa20 /tapsets.cxx
parent2e10c4c99046fc54b86bf3e6a8ebece7a31c2330 (diff)
downloadsystemtap-steved-8fc05e57c1d6468548444a923ef24065a4c8caeb.tar.gz
systemtap-steved-8fc05e57c1d6468548444a923ef24065a4c8caeb.tar.xz
systemtap-steved-8fc05e57c1d6468548444a923ef24065a4c8caeb.zip
2006-12-13 David Smith <dsmith@redhat.com>
* tapsets.cxx (struct dwarf_var_expanding_copy_visitor): Added 'add_probe' member variable. Initialized it in ctor. (dwarf_var_expanding_copy_visitor::visit_target_symbol): Optimization. Instead of generating one entry probe per target variable accessed in a return probe, now just generates one entry probe for all target variables accessed in a particular return probe. It does this by creating a new probe in the new 'add_probe' member variable. (dwarf_derived_probe::dwarf_derived_probe): If add_probe isn't NULL, make sure it gets derived later.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx183
1 files changed, 116 insertions, 67 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index 73e3ed11..b6842e7a 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2916,9 +2916,10 @@ struct dwarf_var_expanding_copy_visitor: public var_expanding_copy_visitor
Dwarf_Die *scope_die;
Dwarf_Addr addr;
block *add_block;
+ probe *add_probe;
dwarf_var_expanding_copy_visitor(dwarf_query & q, Dwarf_Die *sd, Dwarf_Addr a):
- q(q), scope_die(sd), addr(a), add_block(NULL) {}
+ q(q), scope_die(sd), addr(a), add_block(NULL), add_probe(NULL) {}
void visit_target_symbol (target_symbol* e);
};
@@ -3042,25 +3043,25 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
if (add_block == NULL)
{
- add_block = new block;
- add_block->tok = e->tok;
-
- // Synthesize a functioncall to grab the thread id.
- functioncall* fc = new functioncall;
- fc->tok = e->tok;
- fc->function = string("tid");
-
- // Assign the tid to '_dwarf_tvar_tid'.
- assignment* a = new assignment;
- a->tok = e->tok;
- a->op = "=";
- a->left = tidsym;
- a->right = fc;
-
- expr_statement* es = new expr_statement;
- es->tok = e->tok;
- es->value = a;
- add_block->statements.push_back (es);
+ add_block = new block;
+ add_block->tok = e->tok;
+
+ // Synthesize a functioncall to grab the thread id.
+ functioncall* fc = new functioncall;
+ fc->tok = e->tok;
+ fc->function = string("tid");
+
+ // Assign the tid to '_dwarf_tvar_tid'.
+ assignment* a = new assignment;
+ a->tok = e->tok;
+ a->op = "=";
+ a->left = tidsym;
+ a->right = fc;
+
+ expr_statement* es = new expr_statement;
+ es->tok = e->tok;
+ es->value = a;
+ add_block->statements.push_back (es);
}
// (2b) Synthesize an array reference and assign it to a
@@ -3071,21 +3072,23 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
// = _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
// _dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
- arrayindex* ai_tvar = new arrayindex;
- ai_tvar->tok = e->tok;
+ arrayindex* ai_tvar_base = new arrayindex;
+ ai_tvar_base->tok = e->tok;
symbol* sym = new symbol;
sym->name = aname;
sym->tok = e->tok;
- ai_tvar->base = sym;
+ ai_tvar_base->base = sym;
- ai_tvar->indexes.push_back(tidsym);
+ ai_tvar_base->indexes.push_back(tidsym);
// We need to create a copy of the array index in its current
// state so we can have 2 variants of it (the original and one
// that post-decrements the second index).
- arrayindex* at_tvar_postdec = new arrayindex;
- *at_tvar_postdec = *ai_tvar;
+ arrayindex* ai_tvar = new arrayindex;
+ arrayindex* ai_tvar_postdec = new arrayindex;
+ *ai_tvar = *ai_tvar_base;
+ *ai_tvar_postdec = *ai_tvar_base;
// Synthesize the
// "_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]" used as the
@@ -3126,61 +3129,98 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
pc->tok = e->tok;
pc->op = "--";
pc->operand = ai_ctr;
- at_tvar_postdec->indexes.push_back(pc);
+ ai_tvar_postdec->indexes.push_back(pc);
delete_statement* ds = new delete_statement;
ds->tok = e->tok;
- ds->value = at_tvar_postdec;
+ ds->value = ai_tvar_postdec;
add_block->statements.push_back (ds);
// (3) We need an entry probe that saves the value for us in the
- // global array we created. Create an entire script (and let
- // the parser do all the work). The script will look like this:
+ // global array we created. Create the entry probe, which will
+ // look like this:
//
- // global _dwarf_tvar_{name}_{num}
- // global _dwarf_tvar_{name}_{num}_ctr
// probe kernel.function("{function}") {
- // _dwarf_tvar_{name}_{num}[tid(),
- // ++_dwarf_tvar_{name}_{num}_ctr[tid()]]
+ // _dwarf_tvar_tid = tid()
+ // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
+ // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
// = ${param}
// }
- // We need the name of the current probe point, minus the
- // ".return" (or anything after it, such as ".maxactive(N)").
- // Create a new probe point, copying all the components,
- // stopping when we see the ".return" component.
- probe_point* pp = new probe_point;
- for (unsigned c = 0; c < q.base_loc->components.size(); c++)
+ if (add_probe == NULL)
{
- if (q.base_loc->components[c]->functor == "return")
- break;
- else
- pp->components.push_back(q.base_loc->components[c]);
+ add_probe = new probe;
+ add_probe->tok = e->tok;
+
+ // We need the name of the current probe point, minus the
+ // ".return" (or anything after it, such as ".maxactive(N)").
+ // Create a new probe point, copying all the components,
+ // stopping when we see the ".return" component.
+ probe_point* pp = new probe_point;
+ for (unsigned c = 0; c < q.base_loc->components.size(); c++)
+ {
+ if (q.base_loc->components[c]->functor == "return")
+ break;
+ else
+ pp->components.push_back(q.base_loc->components[c]);
+ }
+ pp->tok = e->tok;
+ pp->optional = q.base_loc->optional;
+ add_probe->locations.push_back(pp);
+
+ add_probe->body = new block;
+ add_probe->body->tok = e->tok;
+
+ // Synthesize a functioncall to grab the thread id.
+ functioncall* fc = new functioncall;
+ fc->tok = e->tok;
+ fc->function = string("tid");
+
+ // Assign the tid to '_dwarf_tvar_tid'.
+ assignment* a = new assignment;
+ a->tok = e->tok;
+ a->op = "=";
+ a->left = tidsym;
+ a->right = fc;
+
+ expr_statement* es = new expr_statement;
+ es->tok = e->tok;
+ es->value = a;
+ add_probe->body->statements.push_back (es);
+
+ vardecl* vd = new vardecl;
+ vd->tok = e->tok;
+ vd->name = tidsym->name;
+ vd->type = pe_long;
+ vd->set_arity(0);
+ add_probe->locals.push_back(vd);
}
- pp->tok = e->tok;
- pp->optional = q.base_loc->optional;
-
- // Print the script into the string stream.
- stringstream stp;
- stp << "global " << aname << endl;
- stp << "global " << ctrname << endl;
- stp << "probe ";
- pp->print(stp);
- delete pp;
- // Note that we can't do:
- // ai_tvar->print (stp);
- // here since we need to pre-increment the counter.
- stp << " { " << aname << "[tid(), ++" << ctrname << "[tid()]] = ";
- e->print (stp);
- stp << " }" << endl;
-
- // Parse the generated script
- stapfile *f = parser::parse (q.sess, stp, false);
- assert (f != NULL);
-
- // Add the parsed script to the list of files to be processed.
- q.sess.files.push_back(f);
+
+ // Save the value, like this:
+ // _dwarf_tvar_{name}_{num}[_dwarf_tvar_tid,
+ // ++_dwarf_tvar_{name}_{num}_ctr[_dwarf_tvar_tid]]
+ // = ${param}
+ arrayindex* ai_tvar_preinc = new arrayindex;
+ *ai_tvar_preinc = *ai_tvar_base;
+
+ pre_crement* preinc = new pre_crement;
+ preinc->tok = e->tok;
+ preinc->op = "++";
+ preinc->operand = ai_ctr;
+ ai_tvar_preinc->indexes.push_back(preinc);
+
+ a = new assignment;
+ a->tok = e->tok;
+ a->op = "=";
+ a->left = ai_tvar_preinc;
+ a->right = e;
+
+ es = new expr_statement;
+ es->tok = e->tok;
+ es->value = a;
+
+ add_probe->body->statements.push_back (es);
// (4) Provide the '_dwarf_tvar_{name}_{num}_tmp' variable to
// our parent so it can be used as a substitute for the target
@@ -3326,6 +3366,15 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
if (v.add_block)
this->body->statements.insert(this->body->statements.begin(), v.add_block);
+ // If when target-variable-expanding the probe, we added a new
+ // probe, add it in a new file to the list of files to be processed.
+ if (v.add_probe)
+ {
+ stapfile *f = new stapfile;
+ f->probes.push_back(v.add_probe);
+ q.sess.files.push_back(f);
+ }
+
// Set the sole element of the "locations" vector as a
// "reverse-engineered" form of the incoming (q.base_loc) probe
// point. This allows a user to see what function / file / line