summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--parse.cxx29
-rw-r--r--staptree.cxx13
-rw-r--r--staptree.h1
-rw-r--r--translate.cxx29
5 files changed, 73 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 99d86eb4..69c5ebff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2006-12-21 Josh Stone <joshua.i.stone@intel.com>
+
+ PR 3671
+ * parse.cxx (parser::parse_global): Allow a maxsize on global arrays.
+ * staptree.h (struct vardecl): Add the maxsize field.
+ * staptree.cxx (vardecl::vardecl): Init. maxsize.
+ (vardecl::set_arity): Don't allow arity 0 when there's a maxsize.
+ (vardecl::compatible_arity): Ditto.
+ (vardecl::print): Include maxsize in output.
+ (target_symbol::print): Ditto.
+ * translate.cxx (struct mapvar, mapvar::mapvar): Add maxsize.
+ (mapvar::init): Init maps with the given maxsize if specified, else
+ keep using MAXMAPENTRIES.
+ (mapvar::set): Make the error message give the maxsize.
+ (mapvar::add): Ditto, and check for overflow on pmap add.
+ (c_unparser::getmap): Pass the maxsize from the vardecl to mapvar.
+
2006-12-21 David Smith <dsmith@redhat.com>
* hash.cxx (find_hash): Added two more options into the hash that
diff --git a/parse.cxx b/parse.cxx
index 26792010..881c75bc 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -1043,14 +1043,29 @@ parser::parse_global (vector <vardecl*>& globals, vector<probe*>& probes)
globals.push_back (d);
t = peek ();
+
+ if (t && t->type == tok_operator && t->content == "[") // array size
+ {
+ int64_t size;
+ next ();
+ expect_number(size);
+ if (size <= 0 || size > 1000000) // arbitrary max
+ throw parse_error("array size out of range");
+ d->maxsize = (int)size;
+ expect_known(tok_operator, "]");
+ t = peek ();
+ }
+
if (t && t->type == tok_operator && t->content == "=") // initialization
- {
- next ();
- d->init = parse_literal ();
- d->set_arity(0);
- d->type = d->init->type;
- t = peek ();
- }
+ {
+ if (!d->compatible_arity(0))
+ throw parse_error("only scalar globals can be initialized");
+ d->set_arity(0);
+ next ();
+ d->init = parse_literal ();
+ d->type = d->init->type;
+ t = peek ();
+ }
if (t && t->type == tok_operator && t->content == ",") // next global
{
diff --git a/staptree.cxx b/staptree.cxx
index aa464469..151d6863 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -104,7 +104,7 @@ probe_point::component::component (std::string const & f, literal * a):
vardecl::vardecl ():
- arity (-1), init(NULL)
+ arity (-1), maxsize(0), init(NULL)
{
}
@@ -115,7 +115,7 @@ vardecl::set_arity (int a)
if (a < 0)
return;
- if (arity != a && arity >= 0)
+ if ((arity != a && arity >= 0) || (a == 0 && maxsize > 0))
throw semantic_error ("inconsistent arity", tok);
if (arity != a)
@@ -130,6 +130,8 @@ vardecl::set_arity (int a)
bool
vardecl::compatible_arity (int a)
{
+ if (a == 0 && maxsize > 0)
+ return false;
if (arity == -1 || a == -1)
return true;
return arity == a;
@@ -265,6 +267,8 @@ void target_symbol::print (std::ostream& o) const
void vardecl::print (ostream& o) const
{
o << name;
+ if (maxsize > 0)
+ o << "[" << maxsize << "]";
if (arity > 0 || index_types.size() > 0)
o << "[...]";
if (init)
@@ -277,7 +281,10 @@ void vardecl::print (ostream& o) const
void vardecl::printsig (ostream& o) const
{
- o << name << ":" << type;
+ o << name;
+ if (maxsize > 0)
+ o << "[" << maxsize << "]";
+ o << ":" << type;
if (index_types.size() > 0)
{
o << " [";
diff --git a/staptree.h b/staptree.h
index d4eea008..7585a01f 100644
--- a/staptree.h
+++ b/staptree.h
@@ -395,6 +395,7 @@ struct vardecl: public symboldecl
void set_arity (int arity);
bool compatible_arity (int a);
int arity; // -1: unknown; 0: scalar; >0: array
+ int maxsize; // upperbound on size for arrays
std::vector<exp_type> index_types; // for arrays only
literal *init; // for global scalars only
};
diff --git a/translate.cxx b/translate.cxx
index d37600da..c20cde8d 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -435,12 +435,15 @@ struct mapvar
: public var
{
vector<exp_type> index_types;
+ int maxsize;
mapvar (bool local, exp_type ty,
statistic_decl const & sd,
string const & name,
- vector<exp_type> const & index_types)
+ vector<exp_type> const & index_types,
+ int maxsize)
: var (local, ty, sd, name),
- index_types (index_types)
+ index_types (index_types),
+ maxsize (maxsize)
{}
static string shortname(exp_type e);
@@ -547,11 +550,20 @@ struct mapvar
string add (vector<tmpvar> const & indices, tmpvar const & val) const
{
+ string res = "{ int rc = ";
+
// impedance matching: empty strings -> NULL
if (type() == pe_stats)
- return (call_prefix("add", indices) + ", " + val.qname() + ")");
+ res += (call_prefix("add", indices) + ", " + val.qname() + ")");
else
throw semantic_error("adding a value of an unsupported map type");
+
+ res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " +
+ stringify(maxsize > 0 ?
+ "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
+ + "\"; }";
+
+ return res;
}
string set (vector<tmpvar> const & indices, tmpvar const & val) const
@@ -567,7 +579,10 @@ struct mapvar
else
throw semantic_error("setting a value of an unsupported map type");
- res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check MAXMAPENTRIES\"; }";
+ res += "; if (unlikely(rc)) c->last_error = \"Array overflow, check " +
+ stringify(maxsize > 0 ?
+ "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES")
+ + "\"; }";
return res;
}
@@ -589,7 +604,8 @@ struct mapvar
string init () const
{
string mtype = is_parallel() ? "pmap" : "map";
- string prefix = qname() + " = _stp_" + mtype + "_new_" + keysym() + " (MAXMAPENTRIES" ;
+ string prefix = qname() + " = _stp_" + mtype + "_new_" + keysym() + " (" +
+ (maxsize > 0 ? stringify(maxsize) : "MAXMAPENTRIES") ;
// Check for errors during allocation.
string suffix = "if (" + qname () + " == NULL) rc = -ENOMEM;";
@@ -1905,7 +1921,8 @@ c_unparser::getmap(vardecl *v, token const *tok)
i = session->stat_decls.find(v->name);
if (i != session->stat_decls.end())
sd = i->second;
- return mapvar (is_local (v, tok), v->type, sd, v->name, v->index_types);
+ return mapvar (is_local (v, tok), v->type, sd,
+ v->name, v->index_types, v->maxsize);
}