diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | elaborate.cxx | 36 | ||||
-rw-r--r-- | parse.cxx | 20 | ||||
-rw-r--r-- | stap.1.in | 22 | ||||
-rw-r--r-- | staptree.h | 1 |
5 files changed, 71 insertions, 16 deletions
@@ -1,3 +1,11 @@ +2006-05-08 Li Guanglei <guanglei@cn.ibm.com> + PR 2627 + * elaborate.cxx: epilogue style alias expansion + * parse.cxx: parse += alias definition + * staptree.h: add epilogue_style member to probe_alias + * stap.1.in: add the description of epilogue style alias + * testsuite/parseok/fifteen.stp: testcase for epilogue style alias + 2006-05-05 Roland McGrath <roland@redhat.com> * configure.ac (build_elfutils): Pass CFLAGS to elfutils configure, diff --git a/elaborate.cxx b/elaborate.cxx index f5b0496b..abb91540 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -344,17 +344,33 @@ alias_expansion_builder // there's concatenated code here and we only want one vardecl per // resulting variable. - for (unsigned i = 0; i < alias->body->statements.size(); ++i) - { - statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]); - n->body->statements.push_back(s); - } + if(alias->epilogue_style == true) { + for (unsigned i = 0; i < use->body->statements.size(); ++i) + { + statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]); + n->body->statements.push_back(s); + } - for (unsigned i = 0; i < use->body->statements.size(); ++i) - { - statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]); - n->body->statements.push_back(s); - } + for (unsigned i = 0; i < alias->body->statements.size(); ++i) + { + statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]); + n->body->statements.push_back(s); + } + + } else { + + for (unsigned i = 0; i < alias->body->statements.size(); ++i) + { + statement *s = deep_copy_visitor::deep_copy(alias->body->statements[i]); + n->body->statements.push_back(s); + } + + for (unsigned i = 0; i < use->body->statements.size(); ++i) + { + statement *s = deep_copy_visitor::deep_copy(use->body->statements[i]); + n->body->statements.push_back(s); + } + } derive_probes (sess, n, finished_results, false); } @@ -782,6 +782,8 @@ parser::parse_probe (std::vector<probe *> & probe_ret, bool equals_ok = true; + int epilogue_alias = 0; + while (1) { probe_point * pp = parse_probe_point (); @@ -794,6 +796,15 @@ parser::parse_probe (std::vector<probe *> & probe_ret, next (); continue; } + else if (equals_ok && t + && t->type == tok_operator && t->content == "+=") + { + aliases.push_back(pp); + epilogue_alias = 1; + next (); + continue; + } + else if (t && t->type == tok_operator && t->content == ",") { locations.push_back(pp); @@ -821,6 +832,10 @@ parser::parse_probe (std::vector<probe *> & probe_ret, else { probe_alias* p = new probe_alias (aliases); + if(epilogue_alias) + p->epilogue_style = true; + else + p->epilogue_style = false; p->tok = t0; p->locations = locations; p->body = parse_stmt_block (); @@ -1068,7 +1083,8 @@ parser::parse_probe_point () t = peek (); if (t && t->type == tok_operator - && (t->content == "{" || t->content == "," || t->content == "=")) + && (t->content == "{" || t->content == "," || t->content == "=" + || t->content == "+=" )) break; if (t && t->type == tok_operator && t->content == "(") @@ -1093,7 +1109,7 @@ parser::parse_probe_point () if (t && t->type == tok_operator && t->content == ".") next (); else - throw parse_error ("expected '.' or ',' or '(' or '{' or '='"); + throw parse_error ("expected '.' or ',' or '(' or '{' or '=' or '+='"); } return pl; @@ -403,10 +403,16 @@ with optimized code. Some other events have very little context. New probe points may be defined using "aliases". Probe point aliases look similar to probe definitions, but instead of activating a probe at the given point, it just defines a new probe point name as an alias -to an existing one. This is identified by the "=" assignment -operator. In addition, the statement block that follows an alias +to an existing one. There are two types of alias, i.e. the prologue +style and the epilogue style which are identified by "=" and "+=" +respectively. + +For prologue style alias, the statement block that follows an alias definition is implicitly added as a prologue to any probe that refers -to the alias. For example: +to the alias. While for the epilogue style alias, the statement block +that follows an alias definition is implicitly added as an epilogue to +any probe that refers to the alias. For example: + .SAMPLE probe syscall.read = kernel.function("sys_read") { fildes = $fd @@ -420,7 +426,15 @@ which expands to .nh .IR kernel.function("sys_read") , .hy -with the given assignment as a prologue. Another probe definition +with the given statement as a prologue. And +.SAMPLE +probe syscall.read += kernel.function("sys_read") { + fildes = $fd +} +.ESAMPLE +defines a new probe point with the given statement as an epilogue. + +Another probe definition may use the alias like this: .SAMPLE probe syscall.read { @@ -585,6 +585,7 @@ struct probe_alias: public probe probe_alias(std::vector<probe_point*> const & aliases); std::vector<probe_point*> alias_names; virtual void printsig (std::ostream &o) const; + bool epilogue_style; }; |