forked from lix-project/lix
Make Env smaller
Commit 20866a7031
added a ‘withAttrs’
field to Env, which is annoying because it makes every Env structure
bigger and we allocate millions of them. E.g. NixOS evaluation took
18 MiB more. So this commit squeezes ‘withAttrs’ into values[0].
Probably should use a union...
This commit is contained in:
parent
8ae6d55db1
commit
0a470fc345
|
@ -307,25 +307,26 @@ void mkPath(Value & v, const char * s)
|
||||||
inline Value * EvalState::lookupVar(Env * env, const VarRef & var, bool noEval)
|
inline Value * EvalState::lookupVar(Env * env, const VarRef & var, bool noEval)
|
||||||
{
|
{
|
||||||
for (unsigned int l = var.level; l; --l, env = env->up) ;
|
for (unsigned int l = var.level; l; --l, env = env->up) ;
|
||||||
|
|
||||||
if (var.fromWith) {
|
if (!var.fromWith) return env->values[var.displ];
|
||||||
while (1) {
|
|
||||||
if (!env->values[0]) {
|
while (1) {
|
||||||
if (noEval) return 0;
|
if (!env->haveWithAttrs) {
|
||||||
env->values[0] = allocValue();
|
if (noEval) return 0;
|
||||||
evalAttrs(*env->up, env->withAttrs, *env->values[0]);
|
Expr * attrs = (Expr *) env->values[0];
|
||||||
}
|
env->values[0] = allocValue();
|
||||||
Bindings::iterator j = env->values[0]->attrs->find(var.name);
|
evalAttrs(*env->up, attrs, *env->values[0]);
|
||||||
if (j != env->values[0]->attrs->end()) {
|
env->haveWithAttrs = true;
|
||||||
if (countCalls && j->pos) attrSelects[*j->pos]++;
|
|
||||||
return j->value;
|
|
||||||
}
|
|
||||||
if (env->prevWith == 0)
|
|
||||||
throwEvalError("undefined variable `%1%'", var.name);
|
|
||||||
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
|
||||||
}
|
}
|
||||||
} else
|
Bindings::iterator j = env->values[0]->attrs->find(var.name);
|
||||||
return env->values[var.displ];
|
if (j != env->values[0]->attrs->end()) {
|
||||||
|
if (countCalls && j->pos) attrSelects[*j->pos]++;
|
||||||
|
return j->value;
|
||||||
|
}
|
||||||
|
if (!env->prevWith)
|
||||||
|
throwEvalError("undefined variable `%1%'", var.name);
|
||||||
|
for (unsigned int l = env->prevWith; l; --l, env = env->up) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -829,7 +830,8 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||||
Env & env2(state.allocEnv(1));
|
Env & env2(state.allocEnv(1));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
env2.prevWith = prevWith;
|
env2.prevWith = prevWith;
|
||||||
env2.withAttrs = attrs;
|
env2.haveWithAttrs = false;
|
||||||
|
env2.values[0] = (Value *) attrs;
|
||||||
|
|
||||||
body->eval(state, env2, v);
|
body->eval(state, env2, v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,8 +52,8 @@ struct PrimOp
|
||||||
struct Env
|
struct Env
|
||||||
{
|
{
|
||||||
Env * up;
|
Env * up;
|
||||||
unsigned int prevWith; // nr of levels up to next `with' environment
|
unsigned short prevWith; // nr of levels up to next `with' environment
|
||||||
Expr * withAttrs;
|
bool haveWithAttrs;
|
||||||
Value * values[0];
|
Value * values[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue