aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04 21:24:11 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2012-01-04 21:24:11 +0000
commit35f2a6ba82419d48ed8ebce7b8c3e74e65ac74f2 (patch)
treeeae7ae96104e0d68de31efa9a31a9d75b8c05129 /src/libexpr
parentadaf64a99b0a882249e35768c3f4fe3de104cbb2 (diff)
* Don't use dynamic_cast, it's very slow. "nix-instantiate
/etc/nixos/nixos -A system" spent about 10% of its time in dynamic_cast.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/eval.cc43
-rw-r--r--src/libexpr/eval.hh2
-rw-r--r--src/libexpr/nixexpr.hh2
3 files changed, 23 insertions, 24 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index bba14bc35..3aa35b327 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -404,28 +404,27 @@ void EvalState::mkThunk_(Value & v, Expr * expr)
}
-unsigned long nrAvoided = 0;
-
/* Create a thunk for the delayed computation of the given expression
in the given environment. But if the expression is a variable,
then look it up right away. This significantly reduces the number
of thunks allocated. */
-Value * EvalState::maybeThunk(Env & env, Expr * expr)
-{
- ExprVar * var;
- /* Ignore variables from `withs' because they can throw an
- exception. */
- if ((var = dynamic_cast<ExprVar *>(expr))) {
- Value * v = lookupVar(&env, var->info);
- /* The value might not be initialised in the environment yet.
- In that case, ignore it. */
- if (v) { nrAvoided++; return v; }
- }
+Value * Expr::maybeThunk(EvalState & state, Env & env)
+{
+ Value * v = state.allocValue();
+ mkThunk(*v, env, this);
+ return v;
+}
- Value * v = allocValue();
- mkThunk(*v, env, expr);
- return v;
+unsigned long nrAvoided = 0;
+
+Value * ExprVar::maybeThunk(EvalState & state, Env & env)
+{
+ Value * v = state.lookupVar(&env, info);
+ /* The value might not be initialised in the environment yet.
+ In that case, ignore it. */
+ if (v) { nrAvoided++; return v; }
+ return Expr::maybeThunk(state, env);
}
@@ -560,7 +559,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
vAttr = state.allocValue();
mkThunk(*vAttr, env2, i->second.e);
} else
- vAttr = state.maybeThunk(env2, i->second.e);
+ vAttr = i->second.e->maybeThunk(state, env2);
env2.values[displ++] = vAttr;
v.attrs->push_back(Attr(i->first, vAttr, &i->second.pos));
}
@@ -593,7 +592,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
if (i->second.inherited)
v.attrs->push_back(Attr(i->first, state.lookupVar(&env, i->second.var), &i->second.pos));
else
- v.attrs->push_back(Attr(i->first, state.maybeThunk(env, i->second.e), &i->second.pos));
+ v.attrs->push_back(Attr(i->first, i->second.e->maybeThunk(state, env), &i->second.pos));
}
}
@@ -613,7 +612,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
if (i->second.inherited)
env2.values[displ++] = state.lookupVar(&env, i->second.var);
else
- env2.values[displ++] = state.maybeThunk(env2, i->second.e);
+ env2.values[displ++] = i->second.e->maybeThunk(state, env2);
state.eval(env2, body, v);
}
@@ -623,7 +622,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
{
state.mkList(v, elems.size());
for (unsigned int n = 0; n < v.list.length; ++n)
- v.list.elems[n] = state.maybeThunk(env, elems[n]);
+ v.list.elems[n] = elems[n]->maybeThunk(state, env);
}
@@ -716,7 +715,7 @@ void ExprApp::eval(EvalState & state, Env & env, Value & v)
{
Value vFun;
state.eval(env, e1, vFun);
- state.callFunction(vFun, *state.maybeThunk(env, e2), v);
+ state.callFunction(vFun, *(e2->maybeThunk(state, env)), v);
}
@@ -791,7 +790,7 @@ void EvalState::callFunction(Value & fun, Value & arg, Value & v)
if (j == arg.attrs->end()) {
if (!i->def) throwTypeError("function at %1% called without required argument `%2%'",
fun.lambda.fun->pos, i->name);
- env2.values[displ++] = maybeThunk(env2, i->def);
+ env2.values[displ++] = i->def->maybeThunk(*this, env2);
} else {
attrsUsed++;
env2.values[displ++] = j->value;
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index 694d4407b..1db3453f3 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -346,8 +346,6 @@ public:
void mkAttrs(Value & v, unsigned int expected);
void mkThunk_(Value & v, Expr * expr);
- Value * maybeThunk(Env & env, Expr * expr);
-
/* Print statistics. */
void printStats();
diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh
index 166289b29..1c5cc07af 100644
--- a/src/libexpr/nixexpr.hh
+++ b/src/libexpr/nixexpr.hh
@@ -53,6 +53,7 @@ struct Expr
virtual void show(std::ostream & str);
virtual void bindVars(const StaticEnv & env);
virtual void eval(EvalState & state, Env & env, Value & v);
+ virtual Value * maybeThunk(EvalState & state, Env & env);
};
std::ostream & operator << (std::ostream & str, Expr & e);
@@ -117,6 +118,7 @@ struct ExprVar : Expr
VarRef info;
ExprVar(const Symbol & name) : info(name) { };
COMMON_METHODS
+ Value * maybeThunk(EvalState & state, Env & env);
};
struct ExprSelect : Expr