diff options
author | graydon <graydon> | 2005-12-08 02:33:55 +0000 |
---|---|---|
committer | graydon <graydon> | 2005-12-08 02:33:55 +0000 |
commit | 71572ba8dfa3b045dfdcd0c8e0a2db168659ea10 (patch) | |
tree | 099a29d98018d4ca2e56a1e3cdf476680871eca0 | |
parent | 90b474e36fdcb17b1d57f8bb0c01d87b0f5e0a96 (diff) | |
download | systemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.tar.gz systemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.tar.xz systemtap-steved-71572ba8dfa3b045dfdcd0c8e0a2db168659ea10.zip |
2005-12-07 Graydon Hoare <graydon@redhat.com>
* staptree.cxx (traversing_visitor::visit_foreach_loop): Visit
the base indexable of the foreach loop.
* translate.cxx (c_tmpcounter::visit_foreach_loop): Implement
histogram bucket iteration arm.
(c_unparser::visit_foreach_loop): Likewise.
(c_tmpcounter::visit_arrayindex): Fix typo.
* testsuite/buildok/iterate_histogram_buckets.stp: New test.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | staptree.cxx | 8 | ||||
-rwxr-xr-x | testsuite/buildok/iterate_histogram_buckets.stp | 30 | ||||
-rw-r--r-- | translate.cxx | 125 |
4 files changed, 136 insertions, 39 deletions
@@ -1,3 +1,15 @@ +2005-12-07 Graydon Hoare <graydon@redhat.com> + + * staptree.cxx (traversing_visitor::visit_foreach_loop): Visit + the base indexable of the foreach loop. + + * translate.cxx (c_tmpcounter::visit_foreach_loop): Implement + histogram bucket iteration arm. + (c_unparser::visit_foreach_loop): Likewise. + (c_tmpcounter::visit_arrayindex): Fix typo. + + * testsuite/buildok/iterate_histogram_buckets.stp: New test. + 2005-12-07 Martin Hunt <hunt@redhat.com> * translate.cxx (mapvar::fini): Use _stp_pmap_del() on pmaps. diff --git a/staptree.cxx b/staptree.cxx index 2ad2d906..87c9b383 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -1245,6 +1245,14 @@ traversing_visitor::visit_for_loop (for_loop* s) void traversing_visitor::visit_foreach_loop (foreach_loop* s) { + symbol *array = NULL; + hist_op *hist = NULL; + classify_indexable (s->base, array, hist); + if (array) + array->visit(this); + else + hist->visit(this); + for (unsigned i=0; i<s->indexes.size(); i++) s->indexes[i]->visit (this); s->block->visit (this); diff --git a/testsuite/buildok/iterate_histogram_buckets.stp b/testsuite/buildok/iterate_histogram_buckets.stp new file mode 100755 index 00000000..e7b4e48e --- /dev/null +++ b/testsuite/buildok/iterate_histogram_buckets.stp @@ -0,0 +1,30 @@ +#! stap -p4 + +global foo +global i + +probe begin +{ + print("starting up\n") + i = 0 +} + +probe timer.jiffies(100) +{ + printf("ping %d\n", i) + foo <<< i + if (i++ > 15) + exit() +} + +probe end +{ + print("shutting down\n") + printf("count %d, avg %d\n", @count(foo), @avg(foo)) + foreach (bucket in @hist_log(foo)) + { + if (@hist_log(foo)[bucket] > 0) + printf("bucket %d: %d\n", bucket, @hist_log(foo)[bucket]) + } +} + diff --git a/translate.cxx b/translate.cxx index fe1de0a5..a4ca176d 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1814,6 +1814,38 @@ c_unparser::visit_for_loop (for_loop *s) } +struct arrayindex_downcaster + : public traversing_visitor +{ + arrayindex *& arr; + + arrayindex_downcaster (arrayindex *& arr) + : arr(arr) + {} + + void visit_arrayindex (arrayindex* e) + { + arr = e; + } +}; + + +static bool +expression_is_arrayindex (expression *e, + arrayindex *& hist) +{ + arrayindex *h = NULL; + arrayindex_downcaster d(h); + e->visit (&d); + if (static_cast<void*>(h) == static_cast<void*>(e)) + { + hist = h; + return true; + } + return false; +} + + void c_tmpcounter::visit_foreach_loop (foreach_loop *s) { @@ -1825,13 +1857,44 @@ c_tmpcounter::visit_foreach_loop (foreach_loop *s) { itervar iv = parent->getiter (array); parent->o->newline() << iv.declare(); - s->block->visit (this); } else - { - // FIXME: fill in some logic here! - assert(false); + { + // See commentary in c_tmpcounter::visit_arrayindex for + // discussion of tmpvars required to look into @hist_op(...) + // expressions. + + // First make sure we have exactly one pe_long variable to use as + // our bucket index. + + if (s->indexes.size() != 1 || s->indexes[0]->referent->type != pe_long) + throw semantic_error("Invalid indexing of histogram", s->tok); + + // Then declare what we need to form the aggregate we're + // iterating over, and all the tmpvars needed by our call to + // load_aggregate(). + + aggvar agg = parent->gensym_aggregate (); + agg.declare(*(this->parent)); + + symbol *sym = get_symbol_within_expression (hist->stat); + var v = parent->getvar(sym->referent, sym->tok); + if (sym->referent->arity != 0) + { + arrayindex *arr = NULL; + if (!expression_is_arrayindex (hist->stat, arr)) + throw semantic_error("expected arrayindex expression in iterated hist_op", s->tok); + + for (unsigned i=0; i<sym->referent->index_types.size(); i++) + { + tmpvar ix = parent->gensym (sym->referent->index_types[i]); + ix.declare (*parent); + arr->indexes[i]->visit(this); + } + } } + + s->block->visit (this); } void @@ -1921,8 +1984,24 @@ c_unparser::visit_foreach_loop (foreach_loop *s) } else { - // FIXME: fill in some logic here! - assert(false); + // Iterating over buckets in a histogram. + assert(s->indexes.size() == 1); + assert(s->indexes[0]->referent->type == pe_long); + var bucketvar = getvar (s->indexes[0]->referent); + + aggvar agg = gensym_aggregate (); + load_aggregate(hist->stat, agg); + + symbol *sym = get_symbol_within_expression (hist->stat); + var v = getvar(sym->referent, sym->tok); + v.assert_hist_compatible(*hist); + + o->newline() << "for (" << bucketvar << " = 0; " + << bucketvar << " < " << v.buckets() << "; " + << bucketvar << "++) { "; + o->newline(1); + s->block->visit (this); + o->newline(-1) << "}"; } } @@ -2556,38 +2635,6 @@ c_unparser::load_map_indices(arrayindex *e, } -struct arrayindex_downcaster - : public traversing_visitor -{ - arrayindex *& arr; - - arrayindex_downcaster (arrayindex *& arr) - : arr(arr) - {} - - void visit_arrayindex (arrayindex* e) - { - arr = e; - } -}; - - -static bool -expression_is_arrayindex (expression *e, - arrayindex *& hist) -{ - arrayindex *h = NULL; - arrayindex_downcaster d(h); - e->visit (&d); - if (static_cast<void*>(h) == static_cast<void*>(e)) - { - hist = h; - return true; - } - return false; -} - - void c_unparser::load_aggregate (expression *e, aggvar & agg) { @@ -2702,7 +2749,7 @@ c_tmpcounter::visit_arrayindex (arrayindex *e) { arrayindex *arr = NULL; if (!expression_is_arrayindex (hist->stat, arr)) - throw semantic_error("expected arrayindex expression in printed hist_op", e->tok); + throw semantic_error("expected arrayindex expression in indexed hist_op", e->tok); for (unsigned i=0; i<sym->referent->index_types.size(); i++) { |