From 0a470fc3453f56a0a242d8f467b8079fe0040ff7 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 31 Jul 2013 12:44:21 +0200 Subject: Make Env smaller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 20866a7031ca823055a221653b77986faa167329 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... --- src/libexpr/eval.cc | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'src/libexpr/eval.cc') diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 904a95d16..f891496a7 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -307,25 +307,26 @@ void mkPath(Value & v, const char * s) inline Value * EvalState::lookupVar(Env * env, const VarRef & var, bool noEval) { for (unsigned int l = var.level; l; --l, env = env->up) ; - - if (var.fromWith) { - while (1) { - if (!env->values[0]) { - if (noEval) return 0; - env->values[0] = allocValue(); - evalAttrs(*env->up, env->withAttrs, *env->values[0]); - } - Bindings::iterator j = env->values[0]->attrs->find(var.name); - if (j != env->values[0]->attrs->end()) { - 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) ; + + if (!var.fromWith) return env->values[var.displ]; + + while (1) { + if (!env->haveWithAttrs) { + if (noEval) return 0; + Expr * attrs = (Expr *) env->values[0]; + env->values[0] = allocValue(); + evalAttrs(*env->up, attrs, *env->values[0]); + env->haveWithAttrs = true; } - } else - return env->values[var.displ]; + Bindings::iterator j = env->values[0]->attrs->find(var.name); + 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)); env2.up = &env; env2.prevWith = prevWith; - env2.withAttrs = attrs; + env2.haveWithAttrs = false; + env2.values[0] = (Value *) attrs; body->eval(state, env2, v); } -- cgit v1.2.3