summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgraydon <graydon>2005-12-08 02:33:55 +0000
committergraydon <graydon>2005-12-08 02:33:55 +0000
commit71572ba8dfa3b045dfdcd0c8e0a2db168659ea10 (patch)
tree099a29d98018d4ca2e56a1e3cdf476680871eca0
parent90b474e36fdcb17b1d57f8bb0c01d87b0f5e0a96 (diff)
downloadsystemtap-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--ChangeLog12
-rw-r--r--staptree.cxx8
-rwxr-xr-xtestsuite/buildok/iterate_histogram_buckets.stp30
-rw-r--r--translate.cxx125
4 files changed, 136 insertions, 39 deletions
diff --git a/ChangeLog b/ChangeLog
index 29de812a..e313d7bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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++)
{